通过发布订阅模式实现数据的异步处理,比如异步处理邮件发送
新建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
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.7</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
Application.java
packagecom.example.demo;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassApplication{publicstaticvoidmain(String[] args){SpringApplication.run(Application.class, args);}}
TaskPoolConfig.java
packagecom.example.demo.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.annotation.EnableAsync;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importjava.util.concurrent.Executor;/**
* 线程池参数配置
**/@EnableAsync@ConfigurationpublicclassTaskPoolConfig{/**
* 自定义线程池
**/@BeanpublicExecutortaskExecutor(){//返回可用处理器的Java虚拟机的数量 12int i =Runtime.getRuntime().availableProcessors();System.out.println("系统最大线程数 : "+ i);ThreadPoolTaskExecutor executor =newThreadPoolTaskExecutor();//核心线程池大小
executor.setCorePoolSize(16);//最大线程数
executor.setMaxPoolSize(20);//配置队列容量,默认值为Integer.MAX_VALUE
executor.setQueueCapacity(99999);//活跃时间
executor.setKeepAliveSeconds(60);//线程名字前缀
executor.setThreadNamePrefix("asyncServiceExecutor -");//设置此执行程序应该在关闭时阻止的最大秒数,以便在容器的其余部分继续关闭之前等待剩余的任务完成他们的执行
executor.setAwaitTerminationSeconds(60);//等待所有的任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);return executor;}}
EmailDto.java
packagecom.example.demo.entity;importlombok.Data;@DatapublicclassEmailDto{privateString email;privateString subject;privateString content;}
SendEmailEvent.java
packagecom.example.demo.event;importcom.example.demo.entity.EmailDto;importorg.springframework.context.ApplicationEvent;/**
* 自定义事件
*/publicclassSendEmailEventextendsApplicationEvent{privateEmailDto emailDto;publicSendEmailEvent(EmailDto emailDto){super(emailDto);this.emailDto = emailDto;}publicEmailDtogetEmailDto(){returnthis.emailDto;}}
SendEmailListener.java
packagecom.example.demo.listener;importcom.example.demo.entity.EmailDto;importcom.example.demo.event.SendEmailEvent;importcom.example.demo.service.SendEmailService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.ApplicationListener;importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Component;/**
* 事件监听器
*/@ComponentpublicclassSendEmailListenerimplementsApplicationListener<SendEmailEvent>{@AutowiredprivateSendEmailService sendEmailService;@Async@OverridepublicvoidonApplicationEvent(SendEmailEvent event){EmailDto emailDto = event.getEmailDto();this.sendEmailService.sendEmail(emailDto);}}
SendEmailService.java
packagecom.example.demo.service;importcom.example.demo.entity.EmailDto;publicinterfaceSendEmailService{voidsendEmail(EmailDto emailDto);}
SendEmailServiceImpl.java
packagecom.example.demo.service.impl;importcom.example.demo.entity.EmailDto;importcom.example.demo.service.SendEmailService;importorg.springframework.stereotype.Service;@ServicepublicclassSendEmailServiceImplimplementsSendEmailService{@OverridepublicvoidsendEmail(EmailDto emailDto){try{// 模拟耗时3秒Thread.sleep(3*1000);}catch(Exception e){System.out.println("Email发送异常");}System.out.println("Email发送成功 "+ emailDto);}}
IndexController.java
packagecom.example.demo.controller;importcom.example.demo.entity.EmailDto;importcom.example.demo.event.SendEmailEvent;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.ApplicationEventPublisher;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassIndexController{@AutowiredprivateApplicationEventPublisher publisher;@GetMapping("/sendEmail")publicStringsendEmail(){EmailDto emailDto =newEmailDto();
emailDto.setEmail("[email protected]");
emailDto.setSubject("邮件标题");
emailDto.setContent("邮件内容");// 发布事件
publisher.publishEvent(newSendEmailEvent(emailDto));return"success";}}
参考
- Spring事件机制 ApplicationEventPublisher
版权归原作者 彭世瑜 所有, 如有侵权,请联系我们删除。