开发者

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();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜