В веб-приложении Spring у меня есть несколько компонентов DAO и служебного уровня. Один бин сервисного уровня имеет аннотированные методы @Async / @Scheduled. Эти методы зависят от других (autowired) bean-компонентов.
Я настроил два пула потоков в XML:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="5" />
<property name="queueCapacity" value="5" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<bean id="taskScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="10" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler"/>
Все работает как положено. Моя проблема в том, что я не могу заставить работать чистое отключение пулов задач. Задачи работают с базой данных и файловой системой. Когда я останавливаю веб-приложение, требуется некоторое время, чтобы оно было остановлено. Это указывает на то, что свойство waitForTasksToCompleteOnShutdown
работает. Тем не менее, я получаю IllegalStateExceptions в журнале, указывающий, что некоторые bean-компоненты уже уничтожены, но некоторые потоки рабочих задач все еще выполняются, и они перестают работать, потому что их зависимости уничтожены.
Существует проблема JIRA, которая может иметь отношение: SPR-5387
Мой вопрос таков: есть ли способ сказать Spring, чтобы он инициализировал bean-компоненты executor / scheduler, или есть ли способ сказать Spring, чтобы они сначала уничтожались?
Я понимаю, что разрушение происходит в обратном порядке инициализации. Поэтому последний компонент, инициированный бобом, будет уничтожен первым. Если бины пула потоков будут уничтожены первыми, все выполняющиеся в настоящее время задачи будут завершены и все равно смогут получить доступ к зависимым бинам.
Я также попытался использовать атрибут зависимости от пулов потоков, ссылающийся на мой компонент службы, который имеет аннотации @Async и @Scheduled. Похоже, что они никогда не выполняются, и я не получаю ошибки инициализации контекста. Я предполагаю, что аннотированному служебному компоненту сначала необходимо инициализировать эти пулы потоков, и если я использую «зависит от», я изменяю порядок и делаю их нефункциональными.