更多内容请浏览本人博客
java发送邮件的方法网上有很多,但是大多是属于阻塞式发送,spring 提供了很方便的实现多线程方法,结合spring可以快速实现异步发送邮件.
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- 此外还需引入springboot 核心包-->
- 配置spring连接池
创建配置类,实现AsyncConfigurer
@Configuration
public class AsyncTaskConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 线程池维护线程的最少数量
taskExecutor.setCorePoolSize(10);
// 线程池维护线程的最大数量
taskExecutor.setMaxPoolSize(50);
// 缓存队列
taskExecutor.setQueueCapacity(99999);
// 对拒绝task的处理策略
//(1) 默认的ThreadPoolExecutor.AbortPolicy 处理程序遭到拒绝将抛出运行时RejectedExecutionException;
//(2) ThreadPoolExecutor.CallerRunsPolicy 线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度
//(3) ThreadPoolExecutor.DiscardPolicy 不能执行的任务将被删除;
//(4) ThreadPoolExecutor.DiscardOldestPolicy 如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程名前缀,方便排查问题
taskExecutor.setThreadNamePrefix("order-send-thread-");
// 注意一定要初始化
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
- 创建发送邮件工具类
此工具类出于本人的需要编写,可根据实际需求改写
public class EmailUtils {
// 引入javaMailSender
private JavaMailSender mailSender;
public EmailUtils(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
// 发送简单邮件
public void sendSimpleMail(String from, String to, String cc, String subject, String text) {
if(StringUtils.isBlank(to)){
return;
}
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to.split(","));
if (StringUtils.isNotBlank(cc)) {
message.setCc(cc.split(","));
}
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
}
// 发送带多个附件的邮件
public void sendAttachmentMail(String from, String to, String cc, String subject, String text, List<Attachment> attachments) throws Exception {
if(StringUtils.isBlank(to)){
return;
}
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(from);
helper.setTo(to.split(","));
if (StringUtils.isNotBlank(cc)) {
helper.setCc(cc.split(","));
}
helper.setSubject(subject);
helper.setText(text);
for (Attachment attachment : attachments) {
String attachmentName = attachment.attachmentName;
DataSource attachmentFile = attachment.attachmentFile;
helper.addAttachment(attachmentName, attachmentFile);
}
mailSender.send(mimeMessage);
}
// 发送带单个附件的邮件
public void sendAttachmentMail(String from, String to, String cc, String subject, String text, Attachment attachment) throws Exception {
if (StringUtils.isBlank(to)) {
return;
}
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(from);
helper.setTo(to.split(","));
if (StringUtils.isNotBlank(cc)) {
helper.setCc(cc.split(","));
}
helper.setSubject(subject);
helper.setText(text);
String attachmentName = attachment.attachmentName;
DataSource attachmentFile = attachment.attachmentFile;
helper.addAttachment(attachmentName, attachmentFile);
mailSender.send(mimeMessage);
}
public static class Attachment {
private String attachmentName;
private DataSource attachmentFile;
public Attachment(String attachmentName, DataSource attachmentFile) {
this.attachmentName = attachmentName;
this.attachmentFile = attachmentFile;
}
}
}
- 创建发送邮件service
@Service
@Slf4j
@EnableAspectJAutoProxy(exposeProxy = true)
public class OrderSendService {
@Autowired
private JavaMailSender mailSender;
@Async//注意此注解,有坑
public void asyncSendEmail(String from, String to, String cc, String subject, String text, List<OrderExcelEntity> orderList) throws Exception {
EmailUtils emailUtils = new EmailUtils(mailSender);
DataSource excelDataSource = generateExcelDataSource(orderList);
EmailUtils.Attachment attachment = new EmailUtils.Attachment("XXX.xls", excelDataSource);
emailUtils.sendAttachmentMail(from, to, cc, subject, text, attachment);
}
}
springboot 实现发送邮件的核心方法已完成,引用时最好根据本人实际需要进行改写.
需要注意的是,当本类中非异步方法调用asyncSendEmail()时,怎么也不能实现异步,比方说我需要定时调用此异步发送邮件方法
@Scheduled(cron = "0 1 0/1 * * ? ")
public void sendMailTimer() {
((OrderSendService) AopContext.currentProxy()).asyncSendEmail(from, to, cc,subject,text,orderList);
}
填坑方法:
1.在类上增加 @EnableAspectJAutoProxy(exposeProxy = true) 注解
2.调用时增加 ((OrderSendService) AopContext.currentProxy())
自此springboot 实现异步发送邮件方法已完成,有不对之处,欢迎指正