2012-05-01 3 views
10

Я хочу запустить поток почтовой службы демона при запуске сервера tomcat. Итак, я аннотировал метод с аннотацией @Async.Как запустить демон при запуске сервера весной

У меня есть класс, который реализует интерфейс ApplicationListener. Когда я вызываю свой асинхронный метод из этого класса, он никогда не запускается асинхронно и блокирует текущий поток. И когда я вызываю свой метод async из класса контроллера Spring, он никогда не блокирует и не запускается асинхронно.

Почему метод async успешно выполнен из одного класса, а не из другого класса?

Что я делаю неправильно и как я могу выполнить мой метод асинхронного запуска при запуске сервера ??

Заранее спасибо.

Редактировать: Привет, ребята, я попытался использовать интерфейс InitializingBean, метод @PostConstruct, метод init-метода для вызова метода async, но он никогда не выполнялся. Затем я понял, что мой lazy-init по умолчанию - true, поэтому я делаю lazy-init ложным для своего InitializingBean. Теперь он выполняет мой метод asnyc, но он блокирует текущий поток, и теперь еще одна проблема, с которой я столкнулся, заключается в том, что мой сервер не останавливался грациозно, но я должен сильно остановить свой сервер.

+2

Покажите нам свой код. –

ответ

12

Прежде всего, вам не нужно использовать интерфейс ApplicationListener. Вы работаете с Spring - достаточно контекста приложения.

Во-вторых, вы говорите о Spring @Async, это означает, что ваша задача должна быть запущена из контекста приложения, а компонент компонента Controller - часть его.

Вы должны убедиться, что у вас есть <annotation-driven> в вашем весеннем файле xml.

Вы можете начать свою задачу на функции @PostConstruct:

@Component 
public class SampleBeanImpl implements SampleBean { 

    @Async 
    void doSomething() { … } 
} 


@Component 
public class SampleBeanInititalizer { 

    @Autowired 
    private final SampleBean bean; 

    @PostConstruct 
    public void initialize() { 
    bean.doSomething(); 
    } 
} 
+0

Здравствуйте, Danny, Спасибо, еще один вопрос, как я могу выполнить какой-то метод при запуске сервера. Если я не буду реализовывать интерфейс ApplicationListener. –

+0

см. Мой обновленный ответ. –

+1

Принятое решение не будет работать, как указано в следующей ошибке: https://jira.spring.io/browse/SPR-7560 –

0

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

4

на основе Spring, reference, использование @Async имеет ограничение во время запуска приложения:

@Async не может быть использован в сочетании с обратными вызовами жизненного цикла, такими как @PostConstruct. Чтобы асинхронно инициализировать весенние бобы, вы в настоящее время должны использовать отдельную инициализацию Spring bean, которая затем запускает аннотированный метод .

Итак, в вашем случае может быть хорошо иметь реализацию InitializingBean с вашим целевым компонентом, а затем запустить через этот демон.

2

Вы добавили тег <annotation-driven> в свой контекст приложения? Из Spring reference doc:

Чтобы включить как @Scheduled и @Async аннотаций, просто включить элемент «аннотаций управляемых» из пространства имен задач в вашей конфигурации.

Примечание. Вы должны также рассмотреть возможность создания экземпляра исполнителем экземпляра. Из task schema definition:

Определяет экземпляр ThreadPoolTaskExecutor с размером конфигурируемого бассейна, очередь емкостью, поддержание активности, а значения отвержения-политика. См. Javadoc для аннотации org.springframework.scheduling.annotation.EnableAsync для получения информации о альтернативах этого элемента XML на основе кода.

Итак, чтобы создать исполнителя, который опирается на пул потоков с 5 нитей вы должны сделать следующее:

<task:annotation-driven executor="myExecutor"/> 
<task:executor id="myExecutor" pool-size="5"/> 

Дополнительные опции конфигурации см @EnableAsync javadoc, как указано выше.

1

мой английский - бассейн. необходимо установить класс обслуживания @Lazy (false).

Смежные вопросы