Spring Boot реализует асинхронные события Событие

Spring Boot

учиться никто конец территория , и июнь общий нежелание .

Сцены

Много раз, когда мы завершаем определенные дела, нам нужно отправлять пользователям соответствующие напоминания о сообщениях. Для этой неосновной бизнес-функции мы можем выделить ее и создать событие для ее асинхронного выполнения, тем самым реализовав разделение основного бизнеса и подбизнеса.

выполнить

Определите класс событий Event

Создайте класс, наследуйтеApplicationEventи переопределить конструктор.ApplicationEvent— это класс расширения для всех событий приложения, предоставляемых Spring.

public class NoticeEvent extends ApplicationEvent {

    private static final Logger logger = LoggerFactory.getLogger(NoticeEvent.class);

    /**
     * 接受信息
     */
    private String message;

    public NoticeEvent(String message) {
        super(message);
        this.message = message;
        logger.info("add event success! message: {}", message);
    }

    public String getMessage() {
        return message;
    }
}

Создайте класс прослушивателя событий Listener

Создайте класс для прослушивания указанных событий, которые необходимо реализоватьApplicationListenerИнтерфейс, указывающий, что это класс прослушивателя событий приложения. Обратите внимание, что необходимо добавить@ComponentАннотация для внедрения в контейнер Spring.

@Component
public class NoticeListener implements ApplicationListener<NoticeEvent> {

    private static final Logger logger = LoggerFactory.getLogger(NoticeListener.class);

    @Override
    public void onApplicationEvent(NoticeEvent noticeEvent) {
        logger.info("listener get event, sleep 2 second...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("event message is : {}", noticeEvent.getMessage());
    }
}

выпуск события

Публикация событий очень проста, нужно только использовать Spring.ApplicationEventPublisherпубликовать пользовательские события

@RestController
@RequestMapping("/event")
public class EventController {

    private static final Logger logger = LoggerFactory.getLogger(EventController.class);

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @GetMapping("/notice/{message}")
    public void notice(@PathVariable(name = "message") String message) {
        logger.info("begin >>>>>>");
        applicationEventPublisher.publishEvent(new NoticeEvent(message));
        logger.info("end <<<<<<");
    }
}

контрольная работа

Запустите службу и получите доступ к интерфейсу http://localhost:8080/event/notice/hello

[nio-8080-exec-1] o.y.n.event.controller.EventController   : begin >>>>>>
[nio-8080-exec-1] org.ylc.note.event.event.NoticeEvent     : add event success! message: hello
[nio-8080-exec-1] org.ylc.note.event.event.NoticeListener  : listener get event, sleep 2 second...
[nio-8080-exec-1] org.ylc.note.event.event.NoticeListener  : event message is : hello
[nio-8080-exec-1] o.y.n.event.controller.EventController   : end <<<<<<

Выполнение проходит успешно, но через консольную печать информации обнаруживается, что здесь нет асинхронного выполнения

Асинхронное выполнение

По умолчанию асинхронность не включена, нам нужно вручную настроить асинхронную функцию, это очень просто.класс конфигурациидобавить@EnableAsyncПросто аннотация, эта аннотация используется для объявления выполнения асинхронного метода с поддержкой Spring, который необходимо сопоставить с@ConfigurationПри использовании вместе с аннотациями мы можем напрямую добавить его встартовый классначальство. Затем добавьте метод слушателя@AsyncАннотация, указывающая, что текущий метод выполняется асинхронно.

    @Async
    @Override
    public void onApplicationEvent(NoticeEvent noticeEvent) {
        logger.info("listener get event, sleep 2 second...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("event message is : {}", noticeEvent.getMessage());
    }

Перезапустите службу и повторно получите доступ к интерфейсу:

[nio-8080-exec-1] o.y.n.event.controller.EventController   : begin >>>>>>
[nio-8080-exec-1] org.ylc.note.event.event.NoticeEvent     : add event success! message: hello
[nio-8080-exec-1] o.y.n.event.controller.EventController   : end <<<<<<
[         task-1] org.ylc.note.event.event.NoticeListener  : listener get event, sleep 2 second...
[         task-1] org.ylc.note.event.event.NoticeListener  : event message is : hello

Можно обнаружить, что реализована асинхронная функция, основной поток — nio-8080-exec-1, прослушивающий поток — задача-1. Из ответа браузера видно, что интерфейс возвращается напрямую и не возвращается после выполнения прослушивающего потока.

Пользовательский пул асинхронных потоков

После включения асинхронности будет использоваться пул потоков по умолчанию в Spring, и мы можем настроить этот пул потоков. Создайте класс конфигурации (плюс@Configuration),выполнитьAsyncConfigurerинтерфейс, переопределениеExecutorметод. Здесь мы можем настроить исходную конфигурацию в классе запуска.@EnableAsyncАннотации выпущены в этом классе.

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 自定义异步线程池,若不重写会使用默认的线程池
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程数
        taskExecutor.setCorePoolSize(2);
        // 最大线程数
        taskExecutor.setMaxPoolSize(10);
        // 队列大小
        taskExecutor.setQueueCapacity(15);
        // 线程名的前缀
        taskExecutor.setThreadNamePrefix("async-thread-");
        taskExecutor.initialize();
        return taskExecutor;
    }

    /**
     * 捕捉IllegalArgumentException异常
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new MyAsyncExceptionHandler();
    }

    class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
            log.info("TASK Exception message - " + throwable.getMessage());
            log.info("Method name - " + method.getName());
            for (Object param : objects) {
                log.info("Parameter value - " + param);
            }
        }
    }
}

Перезапустите службу и повторно получите доступ к интерфейсу:

[nio-8080-exec-1] o.y.n.event.controller.EventController   : begin >>>>>>
[nio-8080-exec-1] org.ylc.note.event.event.NoticeEvent     : add event success! message: hello
[nio-8080-exec-1] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService
[nio-8080-exec-1] o.y.n.event.controller.EventController   : end <<<<<<
[ async-thread-1] org.ylc.note.event.event.NoticeListener  : listener get event, sleep 2 second...
[ async-thread-1] org.ylc.note.event.event.NoticeListener  : event message is : hello

Имя асинхронного потока в консоли становится определенным нами async-thread-X, что указывает на то, что конфигурация выполнена успешно.

Доступ к исходному коду

Весь код загружен на Github для быстрого доступа

>>>>>> событие

ежедневные комплименты

Это не легко создать, если вы найдете это полезным,попросить лайкслужба поддержки

Поиск внимания