Как запустить метод после завершения инициализации синглтона Spring? - PullRequest
2 голосов
/ 02 февраля 2012

Используя Spring 3.0.x, я сталкиваюсь с проблемой, при которой выполняется init-метод Бина, и как часть этого получает некоторую информацию, а затем в другом потоке (оригинальный поток init () ожидает в других потоках завершить) пытается получить один или несколько Бинов на основе этой информации. Проблема в том, что эти другие Бины также одиночные и еще не инициализированы. В методе DefaultSingletonBeanRegistry есть блок synchronized () в методах getSingleton ().

Проблема возникает в том, что я пытаюсь получить / инициализировать Бин, пока я инициализирую Бин, поэтому я застреваю с основным потоком в методе init (), а другой поток пытается получить другой одноэлементный Бин , и заблокирован, потому что 1-й поток имеет блокировку.

Итак, как я вижу, у меня есть 2 варианта:

1) Получить Spring для запуска метода ПОСЛЕ того, как синглтон был полностью создан, который выполняет фактическую выборку и обработку данных 2) Придумайте передачу сообщения, которая вернет данные в основной поток, а затем обработает их все в нем, поскольку у него уже есть блокировка монитора

Мысли? Идеи? Как бы я получил # 1 на работу?

Ответы [ 4 ]

5 голосов
/ 02 февраля 2012

Вы пытались реализовать интерфейс InitializingBean

class MyBean implements InitializingBean{

    @Override
    public void afterPropertiesSet(){
       // fetch information, etc
    }
}

Согласно документам:

Интерфейс для реализации bean-компонентами, которые должны реагировать после того, как все их свойства были> установлены BeanFactory: например, для выполнения пользовательской инициализации ...

2 голосов
/ 02 февраля 2012

Вы можете реализовать интерфейс Lifecycle. Обратные вызовы жизненного цикла происходят, когда start()/stop() вызывается во вложенном подклассе AbstractApplicationContext, что происходит после инициализации всех одноэлементных компонентов (введенных зависимостей и вызова методов init). Обратные вызовы жизненного цикла также следуют порядку зависимостей, как и инициализация.

1 голос
/ 02 февраля 2012

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

Например, если у вас есть два боба:

<bean id="bean1" class="my.package.class" />
<bean id="bean2" class="my.package.class2" />
<bean id="bean3" class="my.package.class3" depends-on"bean1, bean2" />

В этом случае bean1 и bean2 будут созданы в неподтвержденном порядке. Spring пытается создать экземпляр на основе порядка XML-файла, но это не гарантируется. Однако гарантируется, что bean3 не будет создан до того, как будут созданы bean1 и bean2.

Я не знаю, изменит ли это ваше состояние расы, но, надеюсь, это должно помочь.

В худшем случае вы всегда можете создать экземпляр всех bean-компонентов, а после создания экземпляра вы можете использовать FactoryMethodInvokingBean для вызова статического метода после создания экземпляра bean-компонента. Еще раз, убедитесь, что вы используете depends-on, чтобы гарантировать, что FactoryMethodInvokingBean вызывается после создания экземпляра синглтон-компонента.

0 голосов
/ 28 марта 2018

Если кто-то ищет более актуальный ответ, который не привязан к конкретной среде (например, Spring), Java предоставляет аннотацию @PostConstruct, которая выполняет то же самое. Использование конфигурации на основе аннотации с Spring распознает эту аннотацию и выполнит метод, аннотированный @PostConstruct после инициализации управляемого компонента.

Льготы включают в себя:

  • Вы удаляете зависимость Spring из своего класса
  • Вы можете назвать метод как хотите

Зачем использовать @PostConstruct?

Некоторые практические примеры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...