SpringBoot如何实现ApplicationEvent事件的监听与发布

其他教程   发布日期:2023年08月10日   浏览次数:447

这篇文章主要介绍“SpringBoot如何实现ApplicationEvent事件的监听与发布”,在日常操作中,相信很多人在SpringBoot如何实现ApplicationEvent事件的监听与发布问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot如何实现ApplicationEvent事件的监听与发布”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

通过发布订阅模式实现数据的异步处理,比如异步处理邮件发送

新建SpringBoot项目

项目结构

.
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── demo
│ ├── Application.java
│ ├── config
│ │ └── TaskPoolConfig.java
│ ├── controller
│ │ └── IndexController.java
│ ├── entity
│ │ └── EmailDto.java
│ ├── event
│ │ └── SendEmailEvent.java
│ ├── listener
│ │ └── SendEmailListener.java
│ └── service
│ ├── SendEmailService.java
│ └── impl
│ └── SendEmailServiceImpl.java
└── resources
├── application.yml
├── static
└── templates

实现代码

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.7.7</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.example</groupId>
  12. <artifactId>demo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>demo</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-devtools</artifactId>
  27. <scope>runtime</scope>
  28. <optional>true</optional>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.projectlombok</groupId>
  32. <artifactId>lombok</artifactId>
  33. <optional>true</optional>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-test</artifactId>
  38. <scope>test</scope>
  39. </dependency>
  40. </dependencies>
  41. <build>
  42. <plugins>
  43. <plugin>
  44. <groupId>org.springframework.boot</groupId>
  45. <artifactId>spring-boot-maven-plugin</artifactId>
  46. <configuration>
  47. <excludes>
  48. <exclude>
  49. <groupId>org.projectlombok</groupId>
  50. <artifactId>lombok</artifactId>
  51. </exclude>
  52. </excludes>
  53. </configuration>
  54. </plugin>
  55. </plugins>
  56. </build>
  57. </project>

Application.java

  1. package com.example.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Application {
  6. public static void main(String[] args) {
  7. SpringApplication.run(Application.class, args);
  8. }
  9. }

TaskPoolConfig.java

  1. package com.example.demo.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.scheduling.annotation.EnableAsync;
  5. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  6. import java.util.concurrent.Executor;
  7. /**
  8. * 线程池参数配置
  9. **/
  10. @EnableAsync
  11. @Configuration
  12. public class TaskPoolConfig {
  13. /**
  14. * 自定义线程池
  15. **/
  16. @Bean
  17. public Executor taskExecutor() {
  18. //返回可用处理器的Java虚拟机的数量 12
  19. int i = Runtime.getRuntime().availableProcessors();
  20. System.out.println("系统最大线程数 : " + i);
  21. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  22. //核心线程池大小
  23. executor.setCorePoolSize(16);
  24. //最大线程数
  25. executor.setMaxPoolSize(20);
  26. //配置队列容量,默认值为Integer.MAX_VALUE
  27. executor.setQueueCapacity(99999);
  28. //活跃时间
  29. executor.setKeepAliveSeconds(60);
  30. //线程名字前缀
  31. executor.setThreadNamePrefix("asyncServiceExecutor -");
  32. //设置此执行程序应该在关闭时阻止的最大秒数,以便在容器的其余部分继续关闭之前等待剩余的任务完成他们的执行
  33. executor.setAwaitTerminationSeconds(60);
  34. //等待所有的任务结束后再关闭线程池
  35. executor.setWaitForTasksToCompleteOnShutdown(true);
  36. return executor;
  37. }
  38. }

EmailDto.java

  1. package com.example.demo.entity;
  2. import lombok.Data;
  3. @Data
  4. public class EmailDto {
  5. private String email;
  6. private String subject;
  7. private String content;
  8. }

SendEmailEvent.java

  1. package com.example.demo.event;
  2. import com.example.demo.entity.EmailDto;
  3. import org.springframework.context.ApplicationEvent;
  4. /**
  5. * 自定义事件
  6. */
  7. public class SendEmailEvent extends ApplicationEvent {
  8. private EmailDto emailDto;
  9. public SendEmailEvent(EmailDto emailDto) {
  10. super(emailDto);
  11. this.emailDto = emailDto;
  12. }
  13. public EmailDto getEmailDto() {
  14. return this.emailDto;
  15. }
  16. }

SendEmailListener.java

  1. package com.example.demo.listener;
  2. import com.example.demo.entity.EmailDto;
  3. import com.example.demo.event.SendEmailEvent;
  4. import com.example.demo.service.SendEmailService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.context.ApplicationListener;
  7. import org.springframework.scheduling.annotation.Async;
  8. import org.springframework.stereotype.Component;
  9. /**
  10. * 事件监听器
  11. */
  12. @Component
  13. public class SendEmailListener implements ApplicationListener<SendEmailEvent> {
  14. @Autowired
  15. private SendEmailService sendEmailService;
  16. @Async
  17. @Override
  18. public void onApplicationEvent(SendEmailEvent event) {
  19. EmailDto emailDto = event.getEmailDto();
  20. this.sendEmailService.sendEmail(emailDto);
  21. }
  22. }

SendEmailService.java

  1. package com.example.demo.service;
  2. import com.example.demo.entity.EmailDto;
  3. public interface SendEmailService {
  4. void sendEmail(EmailDto emailDto);
  5. }

SendEmailServiceImpl.java

  1. package com.example.demo.service.impl;
  2. import com.example.demo.entity.EmailDto;
  3. import com.example.demo.service.SendEmailService;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class SendEmailServiceImpl implements SendEmailService {
  7. @Override
  8. public void sendEmail(EmailDto emailDto) {
  9. try {
  10. // 模拟耗时3秒
  11. Thread.sleep(3 * 1000);
  12. } catch (Exception e) {
  13. System.out.println("Email发送异常");
  14. }
  15. System.out.println("Email发送成功 " + emailDto);
  16. }
  17. }

IndexController.java

  1. package com.example.demo.controller;
  2. import com.example.demo.entity.EmailDto;
  3. import com.example.demo.event.SendEmailEvent;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.context.ApplicationEventPublisher;
  6. import org.springframework.web.bind.annotation.GetMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. @RestController
  9. public class IndexController {
  10. @Autowired
  11. private ApplicationEventPublisher publisher;
  12. @GetMapping("/sendEmail")
  13. public String sendEmail() {
  14. EmailDto emailDto = new EmailDto();
  15. emailDto.setEmail("tom@qq.com");
  16. emailDto.setSubject("邮件标题");
  17. emailDto.setContent("邮件内容");
  18. // 发布事件
  19. publisher.publishEvent(new SendEmailEvent(emailDto));
  20. return "success";
  21. }
  22. }

以上就是SpringBoot如何实现ApplicationEvent事件的监听与发布的详细内容,更多关于SpringBoot如何实现ApplicationEvent事件的监听与发布的资料请关注九品源码其它相关文章!