Как запустить демон при запуске сервера в spring
Я хочу запустить поток почтовой службы демона при запуске сервера tomcat. Итак, я аннотировал метод с аннотацией @Async.
У меня есть класс, который реализует интерфейс ApplicationListener. Когда я вызываю свой асинхронный метод из этого класса, он никогда не запускается асинхронно и блокирует текущий поток. И когда я вызываю свой метод async из класса контроллера spring, он никогда не блокирует и не запускается асинхронно.
Почему метод async успешно выполняется из одного класса, а не из другого класса?
Что я делаю неправильно, и как я могу выполнить мой метод асинхронизации при запуске сервера?
Спасибо заранее.
Изменить: Привет, ребята, я попытался использовать интерфейс InitializingBean, @PostConstruct, метод init-метода для вызова моего метода async, но он никогда не выполнялся. Затем я понял, что мой lazy-init по умолчанию - true, поэтому я делаю lazy-init ложным для своего InitializingBean. Теперь он выполняет мой метод asnyc, но он блокирует текущий поток, и теперь еще одна проблема, с которой я столкнулся, заключается в том, что мой сервер не останавливался изящно, но я должен остановить мой сервер.
Ответы
Ответ 1
Прежде всего вам не нужно реализовывать интерфейс ApplicationListener
. Вы работаете с Spring - достаточно контекста приложения.
Во-вторых, вы говорите о Spring @Async
, это означает, что ваша задача должна быть запущена из контекста приложения, а контроллер bean является его частью.
Вы должны убедиться, что у вас <annotation-driven>
в вашем Spring 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();
}
}
Ответ 2
Основываясь на Spring reference, использование @Async
имеет ограничения при запуске приложения:
@Async
не может использоваться в сочетании с обратными вызовами жизненного цикла, такими как @PostConstruct
. Для асинхронной инициализации Spring beans в настоящее время должны использовать отдельную инициализацию Spring bean, которая вызывает @Async
аннотированный метод для целевого объекта.
Итак, в вашем случае, может быть, было бы хорошо иметь реализацию InitializingBean
с вашей целевой bean, а затем запустить через этот демон.
Ответ 3
Добавили ли тэг <annotation-driven>
в свой контекст приложения? Из справочного документа Spring:
Чтобы включить аннотации @Scheduled и @Async, просто добавьте элемент, управляемый аннотацией, из пространства имен задач в вашей конфигурации.
Обратите внимание, что вы также должны сконфигурировать экземпляр исполнителя. Из определение схемы задач:
Определяет экземпляр ThreadPoolTaskExecutor с настраиваемыми размерами пула, размерами очереди, сохранением и отклонениями. См. Javadoc для аннотации org.springframework.scheduling.annotation.EnableAsync для получения информации о альтернативах на основе кода для этого элемента XML.
Итак, чтобы создать исполнителя, резервное копирование которого осуществляется пулом потоков с 5 потоками, вы должны сделать следующее:
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
Дополнительные параметры конфигурации см. в @EnableAsync javadoc, как указано выше.
Ответ 4
мой английский - это пул.
вы должны установить Service Class @Lazy (false).
Ответ 5
@asyn
является частью структуры spring, используется ли ваш слушатель в контексте spring? Если нет, я предлагаю начать новый поток в вашем асинхронном методе.