『博客开发日记』之将邮件的发送从同步发送改为异步发送

本文最后更新于 2026年4月10日 晚上

将邮件的发送从同步发送改为异步发送


起因

我在测试后台忘记密码接口的时候发现点击发送验证码按钮时要转好久都没才有反应

通过检查后发现在 AuthServiceImpl.sendVerificationCode() 方法中,邮件发送是同步执行的

emailService.sendVerificationCodeByForgotPassword(account, code);

这个调用会阻塞整个请求,直到邮件发送完成才返回响应

这样依赖用户体验就极差

解决办法

解决方法就是使用异步发送邮件

用户点击获取验证码时让接口立即返回

然后邮件在后台发送

这样用户就不用看那个获取验证码按钮在那转圈然后很久才跳转到输入验证码页面

可以做到点击获取验证码立即响应到弹出输入框

然后再等待一段时间收到验证码即可输入

这样响应快用户体验也好

验证码在后台发送用户体验感不会很难受

代码实现

使用 Spring 的 @Async 注解实现异步发送

在启动类(MengZeBlogAdminApplication和MengZeBlogApplication)添加 @EnableAsync 注解


在 EmailServiceImpl 的邮件发送方法添加 @Async 注解


创建异步配置类(AsyncConfig)来优化线程池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* 异步任务配置类
* 用于配置异步邮件发送的线程池
*/
@Configuration
public class AsyncConfig
{
@Bean(name = "asyncExecutor")
public Executor asyncExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

// 核心线程数:保持活跃的最小线程数
executor.setCorePoolSize(5);

// 最大线程数:允许创建的最大线程数
executor.setMaxPoolSize(10);

// 队列容量:等待队列的大小
executor.setQueueCapacity(100);

// 线程名称前缀
executor.setThreadNamePrefix("async-email-");

// 线程空闲时间:超过核心线程数的线程在空闲多久后被回收(秒)
executor.setKeepAliveSeconds(60);

// 拒绝策略:队列满时由调用线程执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

// 等待所有任务完成后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);

// 等待时间(秒)
executor.setAwaitTerminationSeconds(60);

executor.initialize();
return executor;
}
}

在 EmailServiceImpl 的邮件发送方法添加 @Async 注解


说明一下

这样虽然可以提高响应速度

但是用户还是要等带一段时间才会收到验证码

不过即使需要等待但用户体验也提高了不少



PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记』之将邮件的发送从同步发送改为异步发送
http://example.com/2026/04/10/『博客开发日记』之将邮件的发送从同步发送改为异步发送/
作者
云梦泽
发布于
2026年4月10日
更新于
2026年4月10日
许可协议