一、背景说明
1、发送邮件的场景很多
邮件是不仅是企事业单位沟通的重要工具,更是重要的沟通记录和文字留底,在企事业单位中具有非常重要的意义。
因此,系统中能够针对某些事项自动发送邮件的需求也是非常正常的。例如新员工入职、生日等自动发送邮件等。
2、怎么发送邮件
SpringBoot中提供了Email依赖包,可以方便我们快速定制自己邮件发送模块,具体的依赖包是spring-boot-starter-mail
,在很多博客中对他都有比较详细的讲解。本文基于基于这个依赖包,在SpringBoot中实操实现一个自定义的异步邮件发送器。
3、为什么需要异步发邮件
原因不言而喻,主要两方面:(1)发送邮件在新线程中进行,不会阻塞主线程的运行;(2)多线程发送邮件,每封邮件间相互独立,可以并行发送,邮件发送速度提高。
因此,本文基于SpringBoot实现了异步邮件发送器,具体实现步骤如下:
二、实现步骤
(一)导入Email库
编辑pom.xml文件,添加邮件Email的依赖库。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
(二)SMTP配置
发送邮件是通过SMTP服务器来完成的,首先我们需要在applicatim.yml中配置SMTP服务器的连接信息。以163的SMTP服务器为例,配置信息如下:
spring:
mail:
default-encoding: UTF-8
host: smtp.163.com
username: 此处是163邮箱 [email protected]
password: 此处是在163邮箱中开启IMAP/SMTP服务时生成的授权码
注意,需要提前已经开启了163邮箱的SMTP功能,如下图所示。
(三)异步发送邮件
首先,声明Java线程池,并进行基础的配置。
package com.example.demo.wx.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@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;
}
}
然后,定义发送邮件的通用任务。
package com.example.demo.wx.task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@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.setCc(mailbox);
javaMailSender.send(message);
}
}
最后,就可以在业务逻辑中调用发送邮件的通用任务,进行邮件发送了。
public void sendEmailToHR(String hrEmail ){
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("发件人邮箱"); //注意,此处发件人邮箱必须和配置文件中开通SMTP服务的邮箱地址一致
message.setTo(hrEmail); //收件人
message.setSubject("新员工报道提示"); //邮件主题
message.setText("XXX 同学确定将于2021年10月10日,前往C座接待前台报道,请协助完成报道流程"); //邮件内容
emailTask.sendAsync(message);
}