Spring : Injecting the object that launches the ApplicationContext into the ApplicationContext
I want to use Spring inside a legacy application.
The core piece is a class, let's call it LegacyPlugin, that represents a sort of pluggable piece in the application. The problem is that this class is also the database connector, and is used to create lots of other objects, often via constructor injection...
I want to launch an ApplicationContext from the LegacyPlugin, and inject it into the ApplicationContext, via a BeanFactory for example, to create the other objects. The code will then be rewritten, to use setter injection & so on.
I would like to know what is the best way to achieve this. So far, I have a working version using a BeanFactory that uses a ThreadLocal to hold a static reference to the plugin currently executed, but it seems ugly to me...
Below is the code I would like to end up with :
public class MyPlugin extends LegacyPlugin {
public void execute() {
ApplicationContext ctx = new ClassPathXmlApplicationContext();
// Do something here with this, but what ?
ctx.setConfigLoc开发者_Go百科ation("context.xml");
ctx.refresh();
}
}
<!-- This should return the object that launched the context -->
<bean id="plugin" class="my.package.LegacyPluginFactoryBean" />
<bean id="someBean" class="my.package.SomeClass">
<constructor-arg><ref bean="plugin"/></constructor-arg>
</bean>
<bean id="someOtherBean" class="my.package.SomeOtherClass">
<constructor-arg><ref bean="plugin"/></constructor-arg>
</bean>
The SingletonBeanRegistry
interface allows you to manually inject a pre-configured singleton into the context via its registerSingleton
method, like this:
ApplicationContext ctx = new ClassPathXmlApplicationContext();
ctx.setConfigLocation("context.xml");
SingletonBeanRegistry beanRegistry = ctx.getBeanFactory();
beanRegistry.registerSingleton("plugin", this);
ctx.refresh();
This adds the plugin
bean to the context. You don't need to declare it in the context.xml
file.
Actually, this doesn't work... It causes the following error :
BeanFactory not initialized or already closed
call 'refresh' before accessing beans via the ApplicationContext
The final solution is to use GenericApplicationContext :
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.getBeanFactory().registerSingleton("plugin", this);
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions(
new ClassPathResource("context.xml"));
ctx.refresh();
精彩评论