各拡張機能を別々のアプリケーションコンテキストで設定します。各アプリケーションコンテキストでは、BeanPostProcessorを定義し、アプリケーションコンテキストが定義するすべてのBeanを、Beanをアプリケーションコンテキストにマップするレジストリに保存します。
各拡張アプリケーションコンテキストの親となるアプリケーションコンテキストを設定します。この設定ファイルで、Bean名をアプリケーションコンテキスト識別子にマップするBeanを定義します。
<!-- parent.xml -->
<beans>
<bean
id="beanNameToApplicationContextIdMap"
class="java.util.HashMap"/>
</beans>
拡張アプリケーションコンテキストコンフィギュレーションファイルは、BeanPostProcessor
インタフェースを実装するカスタムクラスであるBeanNameToApplicationContextIdMapInserter
のインスタンスを定義します。 applicationContextId
プロパティは、アプリケーションコンテキストを識別する文字列に構成されます。 map
プロパティは、親アプリケーションコンテキストで定義されたマップを更新するようにインスタンスを構成します。
<!-- alpha.xml -->
<beans>
<bean class="com.example.BeanNameToApplicationContextIdMapInserter">
<property name="applicationContextId" value="alpha"/>
<property name="map" ref="beanNameToApplicationContextIdMap"/>
</bean>
<bean id="alphaService" class="...">
</bean>
</beans>
BeanNameToApplicationContextIdMapInserter
ソースコード:
public class BeanNameToApplicationContextIdMapInserter implements BeanPostProcessor {
private String applicationContextId;
private HashMap<String, String> map;
public void setApplicationContextId(String id) {
this.applicationContextId = id;
}
public void setMap(HashMap<String, String> map) {
this.map = map;
}
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
{
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
{
map.put(beanName, applicationContextId);
return bean;
}
}
あなたは親アプリケーションのコンテキストおよび各拡張アプリケーションコンテキストを設定するためにSingletonBeanFactoryLocatorを使用することができます。
<!-- beanRefFactory.xml -->
<beans>
<bean
id="parentApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>parent.xml</value>
</constructor-arg>
</bean>
<bean
id="alphaApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>alpha.xml</value>
</constructor-arg>
<constructor-arg>
<ref bean="parentApplicationContext"/>
</constructor-arg>
</bean>
<bean
id="bravoApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>bravo.xml</value>
</constructor-arg>
<constructor-arg>
<ref bean="parentApplicationContext"/>
</constructor-arg>
</bean>
</beans>
ここで、Beanをアプリケーションコンテキストマップに読み込むコードの例を示します。
public class Main {
private static ApplicationContext getApplicationContext(String name) {
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference bfr = bfl.useBeanFactory(name);
return (ApplicationContext) bfr.getFactory();
}
public static void main(String[] args) {
ApplicationContext parentApplicationContext =
getApplicationContext("parentApplicationContext");
HashMap<String, String> map = (HashMap<String, String>)
parentApplicationContext.getBean("beanNameToApplicationContextIdMap");
System.out.println(map.get("alphaService"));
System.out.println(map.get("bravoService"));
}
}
ありがとうございました。それは興味深い考えのように聞こえる。しかし、どのように私は各設定ファイルの新しいコンテキストを割り当てるのですか? – Stas
現時点でどのように拡張設定ファイルを特定して読み込みますか? – skaffman
現在、私は正規表現を使って設定ファイルをロードしています。例えば、私はproduct - * - config.xmlファイルをロードしています。そのため、拡張機能がproduct-myextension-config.xmlファイルをデプロイするとロードされます。あなたの提案されたアプローチを使用しているようです。命名規則を厳しくし、各拡張モジュールの設定ファイル名を別々に事前定義して、別のコンテキストでそれらを読み込むことができるようにする必要があります。妥当な音です。私はそれを試してみます、ありがとう! – Stas