Анотирането на bean @DependsOn означава ли, че зависимият bean ще бъде създаден или инициализиран?

Използвам Spring 3.0.2. Имам две сравнително прости дефиниции на боб. Единият има @PostConstruct (компонент 'A'), който задейства верига от събития, за които @DependsOn bean (компонент 'B') трябва да бъде подготвен. Изглежда обаче, въпреки че казах, че зърното „A“ зависи от зърното „B“, събитията (методите на жизнения цикъл) на зърното „A“ се изпълняват преди зърното „B“ да бъде напълно инициализирано.

Заявяването, че bean е "зависим" чрез @DependsOn (или по този въпрос, зависи от дефиницията на bean) означава ли, че методите на жизнения цикъл на зависимия bean ще бъдат завършени преди bean, който е зависим от споменатия bean?

Ще бъдат ли завършени методите на жизнения цикъл на bean 'B' преди bean 'A'?

АКТУАЛИЗАЦИЯ

Bean A е потребителски клас, който използва JMS шаблон, за да изпрати съобщение, което съобщава, че е инициализирал.

Получателят на споменатото съобщение го обработва и препраща неговата конфигурация към MessageListeningContainer (Bean B).

Първата част се случва преди Bean B да бъде стартиран от DefaultLifecycleProcessor.

@Component
@DependsOn("beanB")
public class BeanA {
    @PostConstruct
    public void init() {
        // do stuff
    }
}

<bean id="beanB" class="org.springframework.jms.listener.DefaultMessageListenerContainr">
    <!-- other configuration -->
</bean>

Добавих в моя init метод инжектирането на bean b плюс два оператора за регистриране:

container.isRunning();
container.isActive();

Погледнах пролетния източник и isActive е настроен на true след метода за инициализация (doInitialized е завършен). IsRunning се задава след завършване на doStart. doStart се задейства от DefaultLifecycleProcessor, който се появява след извикването на анотираните методи @PostConstruct.

Как мога да гарантирам, че моят метод Postconstruct се извиква СЛЕД като bean b е инициализиран И стартиран?


person Community    schedule 11.01.2012    source източник
comment
(Скелетът на вашите класови дефиниции може да помогне за разбирането; открих, че е малко трудно за четене.)   -  person Dave Newton    schedule 11.01.2012


Отговори (1)


Във вашия конкретен случай @PostConstruct методът на bean A няма да бъде извикан, докато B не бъде напълно инициализиран, т.е. всички негови зависимости се инжектират и неговият @PostConstruct завършва с изпълнението.

актуализирано: Тъй като тук разчитате на функционалността на жизнения цикъл на Spring, можете ли да внедрите Lifecycle в A и да преместите вашето JMS извикване към start() метод там?

person mrembisz    schedule 11.01.2012
comment
Това изглежда е вярно. Инспектирах моето зърно Б по време на конструирането на зърно А. Въпреки това, Bean B не само има реализация на инициализация (InitializingBean), но също така имплементира интерфейса LifeCycle. Изглежда, че LifecycleProcessor се извиква след инициализиране на бобовете. Така че изглежда, че трябва да променя моя пост конструкция, за да бъде реализация на фаза от жизнения цикъл. - person ; 11.01.2012
comment
Копаейки по-нататък, виждам, че анотациите се обработват първо, последвани от интерфейси. Това е истинският проблем. Тъй като Bean B имплементира интерфейса, неговият метод за стартиране на жизнения цикъл не се извиква до анотирания метод. - person ; 11.01.2012
comment
@predhme Може би използването на механизъм за зависимост на bean не е най-добрият начин за организиране на асинхронни взаимодействия при обработка, с които изглежда имате работа тук. Обмисляли ли сте отделянето на стартирането на обработката от инициализацията на bean и да го организирате от специален единичен bean? Тук все още липсва много информация, за да бъде наистина полезна. - person mrembisz; 11.01.2012
comment
Актуализирах моя клас, така че да прилага интерфейса на жизнения цикъл. Методът init промених, за да внедря метода start. Този метод обаче никога не се извиква сега. Това ли е защото моят bean е @Component? - person ; 12.01.2012
comment
@predhme Добре, трябва да използвате SmartLifecycle вместо Lifecycle и да внедрите isAutoStartup като return true - person mrembisz; 12.01.2012
comment
Приложих SmartLifeCycle и открих, че създава проблеми с внедряването на стоп (Runnable). По-късно намерих интерфейс ApplicationListener‹ContextRefreshedEvent›. Сега работи перфектно. Благодаря - person ; 13.01.2012