SingletonBeanFactoryLocatorとContextSingletonBeanFactoryLocatorを使う

Springでは、SingletonBeanFactoryLocatorとContextSingletonBeanFactoryLocatorというものが用意されてます。
ずばり、これらはBeanFactory、ApplicationContextのインスタンスを返してくれるファクトリと理解しました。
SingletonBeanFactoryLocatorは、BeanFactoryのファクトリで、
ContextSingletonBeanFactoryLocatorは、ApplicationContextのファクトリです。



例えば、コンテナ外のインスタンスが、コンテナ内のインスタンスへアクセスしたい場合を考えます。
そのとき、コンテナ内のインスタンスを複数のコンテキストで管理しているとすると、コンテナ外の
インスタンスはいろいろな場所で各コンテキストへアクセスすることになります。
うーん、非常に保守性が悪そうです。
そこで、BeanFactory、ApplicationContextのファクトリであるSingletonBeanFactoryLocator、
ContextSingletonBeanFactoryLocatorを利用することで、コンテナ外のインスタンスからコンテナ内の
インスタンスへのアクセスを一元化することが出来るわけです*1


では、早速使ってみましょう。

まず、複数のコンテキストの名前を1つのXMLへまとめます。
XMLのファイル名ですが、SingletonBeanFactoryLocatorの場合は、「beanRefFactory.xml」。
ContextSingletonBeanFactoryLocatorの場合は、「beanRefContext.xml」という名前にします。
これは、引数のない getInstance() メソッドを呼び出した場合に、上記の名前でクラスパス上を検索するようになっているからです。

  • beanRefContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="context1" 
      class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg>
      <list>
        <value>chapter01/chapter01.xml</value>
        <value>chapter02/chapter02.xml</value>
      </list>
    </constructor-arg>
  </bean>
  <bean id="context2" 
      class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg>
      <list>
        <value>chapter03/chapter03.xml</value>
      </list>
    </constructor-arg>
  </bean>
</beans>
  • コード
	public static void main(String[] args) {
		try {
			BeanFactoryLocator locator = SingletonBeanFactoryLocator.getInstance();
			BeanFactoryReference ref = locator.useBeanFactory("context1");
			ApplicationContext ctx = (ApplicationContext)ref.getFactory();
			
			Person person = (Person)ctx.getBean("person");
			
			System.out.println(person.getName());

		} catch(Exception e) {
			e.printStackTrace();
		}
	}


ContextSingletonBeanFactoryLocatorのgetInstance()メソッドを呼び出します。
すると、自分自身のインスタンスを返却します。
(このインスタンスはシングルトンになります。というわけで、名前にSingletonと付いているみたい。)

次に、取得したBeanFactoryLocatorインスタンスのuseBeanFactoryを呼び出します。
この時、beanRefContext.xmlに定義されているbean要素のid属性を引数に渡すと、
該当するコンテキストの参照(BeanFactoryReference*2)が取得されます。


まぁ、なんとなく使い方がわかった感じです。(ほんとか?!)
とりあえず今日は眠いので寝ることにします。。。
なぁなぁだな。。。

*1:認識違ってないかな。。

*2:インスタンスが必要とされるまでコンテナの初期化を遅延したりするようです。