Вызвать отложенный метод из метода сервиса. Паттерн наблюдатель
Есть post метод putMessage(Some object) который принимает на вход данные, обрабатывает их и возвращает пользователю сообщение "загрузка файла прошла успешно".
После того как метод обработал данные и перед тем как вернуть пользователю "загрузка файла прошла успешно", мне нужно еще запустить отдельный метод void2() который выполняет работу около 2-3 часов.
Как вызвать внутри putMessage(Some object) этот метод чтобы его выполнение началось отдельно и клиент не ждал сообщение 2-3 часа. Я слышал что это можно реализовать через Наблюдателя. есть для этого инструмент в Spring?
т.е.
String putMessage(Some object){
// 1. обработка данных object
// 2. вызов void2() * - вынести в отдельный поток
// 3. return "загрузка файла прошла успешно";
}
Ответы (1 шт):
Сначала нужно включить инфраструктуру для запуска асинхронных методов.
В java конфигyрации нужно добавить аннотацию @EnableAsync:
@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }
или в xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"
>
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
...
</beans>
Потом, помечаете метод, который хотите чтобы выполнялся в отдельном потоке, аннотацией @Async:
@Async
public void void2() {
// этот метод выполнится в отдельном потоке
}
Это самая простая конфигурация. Дополнительно можно еще:
- конфигурировать executor, например, сколько потоков для асинхронных задач будет доступно
- добавлять обработчик ошибок, для асинхронных методов
- запускать метод из основного (как в этом случае
putMessage), и ждать когда закончится выполнение и вернуть результат работы
Ну и тут есть полностью рабочий пошаговый пример с объяснением по-русски.