Spring: внедрение объекта, запускающего ApplicationContext, в ApplicationContext - PullRequest
4 голосов
/ 29 марта 2011

Я хочу использовать Spring внутри унаследованного приложения.

Основной компонент - это класс, назовем его LegacyPlugin , который представляет собой своего рода подключаемый элемент в приложении.Проблема заключается в том, что этот класс также является соединителем базы данных и используется для создания множества других объектов, часто с помощью внедрения в конструктор ...

Я хочу запустить ApplicationContext из LegacyPlugin и вставьте его в ApplicationContext, например, через BeanFactory, чтобы создать другие объекты.Затем код будет переписан с использованием инжектирования сеттера и т. Д.

Я хотел бы знать, каков наилучший способ добиться этого.До сих пор у меня есть рабочая версия, использующая BeanFactory, которая использует ThreadLocal для хранения статической ссылки на выполняемый в данный момент плагин, но мне это кажется уродливым ...

Ниже приведен код, который я хотел бы завершитьс:

public class MyPlugin extends LegacyPlugin {

    public void execute() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext();
        // Do something here with this, but what ?
        ctx.setConfigLocation("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>

Ответы [ 2 ]

4 голосов
/ 30 марта 2011

Интерфейс SingletonBeanRegistry позволяет вам вручную вводить предварительно сконфигурированный синглтон в контекст с помощью его метода registerSingleton, например:

ApplicationContext ctx = new ClassPathXmlApplicationContext();
ctx.setConfigLocation("context.xml");

SingletonBeanRegistry beanRegistry = ctx.getBeanFactory();
beanRegistry.registerSingleton("plugin", this);

ctx.refresh();

Это добавляет бин plugin в контекст,Вам не нужно объявлять это в файле context.xml.

0 голосов
/ 14 апреля 2011

На самом деле, это не работает ... Это вызывает следующую ошибку:

BeanFactory not initialized or already closed
call 'refresh' before accessing beans via the ApplicationContext

Окончательное решение - использовать GenericApplicationContext :

GenericApplicationContext ctx = new GenericApplicationContext();
ctx.getBeanFactory().registerSingleton("plugin", this);
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions(
    new ClassPathResource("context.xml"));
ctx.refresh();
...