背景:
在某个业务执行签到时,会根据疫情风险等级判断是否发送告警邮件:如果员工的签到地点为中高风险地区则需要发送邮件给对应人事进行告警。
在签到过程中的业务逻辑相对耗时,且需要保存数据同步执行;如果发送邮件再做成同步执行的,势必导致签到执行时间过长,影响用户体验。
而发送邮件跟保存签到数据没有直接关联,所以使用异步执行能提高用户体验。
参考:
整合:
-
官方文档: Interface JavaMailSender
-
maven依赖:编辑
pom.xml
文件,添加依赖库<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
-
设置SMTP服务器信息
发送邮件是通过SMTP服务器来完成的,所以我们要配置一下SMTP服务器的连接信息,以163邮箱为例:
spring: …… mail: default-encoding: UTF-8 host: smtp.163.com username: *************@163.com password: 此处是密码
-
接下来我们把系统内的常用邮箱声明一下,以后会用到这些邮箱往外发送邮件,或者给这些邮箱发送内部邮件。例如,员工签到地点是疫情高风险地区,那么就应该向HR邮箱发送邮件,告知人事总监有员工需要隔离。
email: system: *********@163.com hr: **********@qq.com
实例:
-
开启异步多线程执行:
在主类上面开启
@EnableAsync
注解 -
创建
ThreadPoolConfig
类,声明Java线程池(看具体服务器配置)@Configuration public class ThreadPoolConfig { @Bean("AsyncTaskExecutor") public AsyncTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(8); // 设置最大线程数 executor.setMaxPoolSize(16); // 设置队列容量 executor.setQueueCapacity(32); // 设置线程活跃时间(秒) executor.setKeepAliveSeconds(60); // 设置默认线程名称 executor.setThreadNamePrefix("task-"); // 设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
-
创建
EmailTask
类,定义线程任务@Component @Scope("prototype") public class EmailTask implements Serializable { @Autowired private JavaMailSender javaMailSender; @Value("${emos.email.system}") private String mailbox; @Async public void sendAsync(SimpleMailMessage message){ message.setFrom(mailbox); javaMailSender.send(message); } }
-
在业务层中实现发送告警邮件:
@Value("${emos.email.hr}") private String hrEmail; @Autowired private EmailTask emailTask;
HashMap<String, String> map = userDao.searchNameAndDept(userId); String name = map.get("name"); String deptName = map.get("dept_name"); deptName = deptName != null ? deptName : ""; SimpleMailMessage message = new SimpleMailMessage(); message.setTo(hrEmail); message.setSubject("员工" + name + "身处高风险疫情地区警告"); message.setText(deptName + "员工" + name + "," + DateUtil.format(new Date(), "yyyy年MM月dd日") + "处于" + address + ",属于新冠疫情高风险地区,请及时与该员工联系,核实情况!"); emailTask.sendAsync(message);