Запуск только подмножества всех компонентов в applicationcontext

#java #spring

#java #spring

Вопрос:

У нас есть настройка, в которой в ApplicationContext определено множество компонентов, но в зависимости от обстоятельств необходимо запускать только подмножество этих компонентов (и под запуском я подразумеваю обратные вызовы жизненного цикла и метод start ()).).

В принципе, то, что я хотел бы сделать, это вызвать «start» для одного компонента и запустить все зависимости этого компонента в обычном порядке запуска компонента, но ничего больше.

Существует ли какой-либо существующий код для чего-то подобного? Если нет, какой был бы хороший способ реализовать это?

Ответ №1:

Обычно я разбиваю конфигурацию компонента на отдельные файлы и просто импортирую файл, содержащий необходимые компоненты. Если вы можете избежать циклических зависимостей, вы можете импортировать файлы друг в друга. Например, у вас может быть service.xml определяется следующим образом

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <description>Service and lower layer beans.</description>

    <context:component-scan base-package="com.gamma.purple"
        use-default-filters="false">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Service" />
    </context:component-scan>

    <import resource="dao.xml" />

</beans>
  

Поскольку dao.xml не должно быть зависимостей от service.xml если бы вам нужны были только компоненты dao, вы могли бы просто импортировать этот файл, и никакие служебные компоненты не были бы загружены.

Комментарии:

1. Спасибо — отдельные файлы конфигурации для меня сейчас не вариант. Идея мне очень понятна, спасибо, что указали на нее.

Ответ №2:

Вы также можете установить отложенную инициализацию для компонентов, чтобы они загружались при необходимости. Пример bean-узла из http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/beans.html#beans-factory-lazy-init :

 <bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
  

Комментарии:

1. Спасибо! К сожалению, это также не решение для меня, поскольку мне нужно, чтобы компоненты были настроены , но не запущены . Lazy-init также предотвращает настройку.

2. Хорошо, итак, что вы подразумеваете под «запущен»?

3. «и под запущенным я подразумеваю обратные вызовы жизненного цикла и метод start()». Прямо из вопроса. static.springsource.org/spring/docs/3.0.x/javadoc-api/org /…

4. Ах, я, должно быть, пропустил это, когда впервые прочитал вопрос. Да, для этого вам, вероятно, потребуется ручная вставка в контекст или использование composition для инициализации компонентов и подготовки их к вставке в объекты, реализующие жизненный цикл. Таким образом: объекты, которые содержат состояние, будут инициализироваться быстро, и объекты жизненного цикла будут иметь зависимость от этих объектов; объекты жизненного цикла будут инициализироваться лениво и, следовательно, будут запускаться () только по ссылке.

5. Хм, не совсем уверен, что ты имеешь в виду. Хотя — все объекты должны быть инициализированы (сконфигурированы), но запускать следует только некоторые. Мне нелегко разделить части, которые должны быть сконфигурированы, и части, которые требуют запуска, для разделения объектов.

Ответ №3:

Вы могли бы выделить подмножество компонентов в отдельный XML-файл и использовать его для создания нового контекста приложения spring. Этот новый контекст может ссылаться на основной контекст приложения (и определенные в них компоненты), который инициализируется во время запуска приложения.

 ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{...}, parentContext);
// once you have finished using it, close the context
ctx.close();
  

Комментарии:

1. Да, я знаю о родительских контекстах приложений. Однако в вашем предложении вы говорите об отделении подмножества компонентов в отдельном файле — однако мне нужны все компоненты, настроенные и присутствующие в контексте, но не запущенные.