Означает ли аннотирование bean-компонента @DependsOn, что зависимый bean-компонент будет создан или инициализирован?

Я использую Spring 3.0.2. У меня есть два относительно простых определения bean. У одного есть @PostConstruct (компонент "A"), который запускает цепочку событий, к которым должен быть готов компонент @DependsOn (компонент "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>

Я добавил в свой метод инициализации инъекцию bean-компонента b плюс два оператора регистрации:

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

Я посмотрел на источник spring, и для isActive установлено значение true после метода Initialization (doInitialized завершен). isRunning устанавливается после завершения doStart. DoStart запускается DefaultLifecycleProcessor, который возникает после вызова аннотированных методов @PostConstruct.

Как я могу гарантировать, что мой метод Postconstruct вызывается ПОСЛЕ того, как компонент b был инициализирован И запущен?


person Community    schedule 11.01.2012    source источник
comment
(Скелет ваших определений классов может помочь пониманию; я нашел это немного трудным для чтения.)   -  person Dave Newton    schedule 11.01.2012


Ответы (1)


В вашем конкретном случае метод @PostConstruct bean-компонента A не будет вызываться до тех пор, пока B не будет полностью инициализирован, т.е. все его зависимости внедряются, и его @PostConstruct завершает выполнение.

обновлено: поскольку здесь вы полагаетесь на функциональность Spring Lifecycle, можете ли вы реализовать Lifecycle в A и переместить туда вызов JMS в метод start()?

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