TransWikia.com

Вызвать отложенный метод из метода сервиса. Паттерн наблюдатель

Stack Overflow на русском Asked by pra_soul_owl on December 16, 2021

Есть post метод putMessage(Some object) который принимает на вход данные, обрабатывает их и возвращает пользователю сообщение "загрузка файла прошла успешно".

После того как метод обработал данные и перед тем как вернуть пользователю "загрузка файла прошла успешно", мне нужно еще запустить отдельный метод void2() который выполняет работу около 2-3 часов.

Как вызвать внутри putMessage(Some object) этот метод чтобы его выполнение началось отдельно и клиент не ждал сообщение 2-3 часа. Я слышал что это можно реализовать через Наблюдателя. есть для этого инструмент в Spring?

т.е.

String putMessage(Some object){
    // 1. обработка данных object
    // 2. вызов void2() * - вынести в отдельный поток
    // 3. return "загрузка файла прошла успешно";
}

One Answer

Сначала нужно включить инфраструктуру для запуска асинхронных методов.

В 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() {
    // этот метод выполнится в отдельном потоке
}

Это самая простая конфигурация. Дополнительно можно еще:

  1. конфигурировать executor, например, сколько потоков для асинхронных задач будет доступно
  2. добавлять обработчик ошибок, для асинхронных методов
  3. запускать метод из основного (как в этом случае putMessage), и ждать когда закончится выполнение и вернуть результат работы

Ну и тут есть полностью рабочий пошаговый пример с объяснением по-русски.

Answered by Roman Konoval on December 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP