SpringBoot专题学习Part29:SpringBoot的Async异步任务、Scheduled定时任务、mail邮件发送任务

Dianthe ·
更新时间:2024-11-10
· 847 次阅读

一、Async异步任务

在Java应用中绝大多数情况下默认都是通过同步的方式来实现交互处理的
但在处理与第三方系统交互的时候 容易造成响应迟缓的情况
可以使用多线程来完成此类任务 但其实 在Spring 3.x之后 已经内置了@Async注解来完美解决该问题

首先来模拟一个同步任务响应迟缓的场景 以供比较:
Service:

@Service public class AsyncService { public void hello() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello"); } }

Controller:

@RestController public class AsyncController { @Autowired AsyncService asyncService; @GetMapping("/hello") public String hello() { asyncService.hello(); return "success"; } }

此时 若访问/hello 则需要先等待两秒才可在页面显示出"success"结果 控制台打印"Hello"字样

开启异步任务:

在主程序类上添加@EnableAsync注解来开启异步注解功能:

@SpringBootApplication @EnableAsync // 开启异步注解功能 public class SpringbootTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringbootTaskApplication.class, args); } }

然后 给要进行异步任务的方法上添加@Async注解即可:
添加该注解之后 Spring就会自动开启一个线程池进行调用

@Service public class AsyncService { // 用@Async注解来说明这是一个异步方法 @Async public void hello() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello"); } }

此时 若访问/hello 直接可在页面显示出"success"结果 然后等待两秒后在控制台打印"Hello"字样 实现了异步

二、定时任务

在项目开发中经常需要执行一些定时的任务
例如 在每天凌晨时候分析一次前一天的日志信息
Spring提供了异步执行任务调度的方式 提供了两个注解:@EnableScheduling@Scheduled

定时任务使用cron表达式来指定定时的时间

cron表达式:

在这里插入图片描述
星期可以用英文前三位 或是数字
用数字的时候 1-6代表周一到周六 0和7都可代表周日
在这里插入图片描述
枚举
例:0,1,2,3,4 * * * * MON-SAT
意为:周一到周六无论什么时候 每当处在0,1,2,3,4秒时 运行一次

区间
例:0-4 * * * * MON-SAT
意为:周一到周六无论什么时候 每当处在0,1,2,3,4秒时 运行一次

步长
指定每隔多长时间执行一次
例:0/4 * * * * MON-SAT
意为:周一到周六无论什么时候 从0秒开始启动 每隔4秒 运行一次

?问号
用于日和星期的冲突匹配
例:0 15 12 * 1 MON 这里的和MON起了冲突 因为代表每天 而MON代表周一 并不是每天都是周一 会起冲突
因此应改为0 15 12 ? 1 MON 使用问号来进行冲突匹配

LLast
WWorkday
CCalendar

使用:

在主程序类上添加@EnableScheduling注解来开启基于注解的定时任务功能:

@SpringBootApplication @EnableScheduling // 开启基于注解的定时任务 public class SpringbootTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringbootTaskApplication.class, args); } }

然后 给要进行异步任务的方法上添加@Scheduled注解即可:
表达式共有六位 每位之间用空格进行分隔
格式:second(秒) minute(分) hour(时) day of month(日) month(月) day of week(周几)
例:0 * * * * MON-FRI 代表周一到周五 每分钟启动一次

@Scheduled(cron = "0 * * * * MON-SAT") public void hello() { System.out.println("Hello"); }

部分cron表达式案例:

0 0/5 14,18 * * ?:每天14点整合18点整 每隔5分钟执行一次 0 15 10 ? * 1-6:每个月周一到周六的10:15分执行一次 0 0 2 ? * 6L:每个月的最后一个周六的凌晨2点执行一次 0 0 2 LW * ?:每个月的最后一个工作日的凌晨2点执行一次 0 0 2-4 ? * 1#1:每个月的第一个周一的凌晨2点到4点这期间 每个整点执行一次(会执行三次:分别是2点 3点 4点执行) 三、邮件任务

邮件发送的流程是这样的:
例如 一个qq邮箱要发送到163邮箱
发邮件的时候 并不是两个邮箱地址直接交互的
而是发送者(qq邮箱)要先用账号密码登录qq邮箱服务器
之后以此账户为名 发送邮件给接收者(163邮箱)
发送的时候是qq邮箱服务器发送邮件给163邮箱服务器
然后接收者从163邮箱服务器获取邮件

邮件发送需要spring-boot-starter-mail

为此 首先 引入依赖: org.springframework.boot spring-boot-starter-mail 然后 进行配置:

为安全起见 配置的password并不是真实的密码 而是授权码
在这里插入图片描述
(在邮箱的设置页面中获取授权码)

# 配置发送者的邮箱用户名 spring.mail.username=1111111111@qq.com # 配置授权码 并不是真实的密码 spring.mail.password=fcddfhqwzksxjhjg # 配置SMTP服务器地址 spring.mail.host=smtp.qq.com # 开启使用SSL安全连接 spring.mail.properties.mail.smtp.ssl.enable=true

ps:这个使用SSL安全连接貌似qq邮箱不加也能正常收发
但部分邮箱收发时有可能会报错

最后 就是发送邮件了

首先 注入JavaMailSenderImpl:

@Autowired JavaMailSenderImpl javaMailSender;

发送简单邮件:

// 创建一个简单邮件信息 SimpleMailMessage simpleMailMessage=new SimpleMailMessage(); // 邮件信息设置 // 设置标题 simpleMailMessage.setSubject("【xx网】恭喜!注册成功!"); // 设置内容 simpleMailMessage.setText("您在xx网刚刚注册了一个账户,接下来您可以尽情使用了。"); // 设置发送目的地邮箱地址 simpleMailMessage.setTo("2222222222@qq.com"); // 设置发送者邮箱地址 simpleMailMessage.setFrom("1111111111@qq.com"); // 发送邮件 javaMailSender.send(simpleMailMessage);

在这里插入图片描述
在这里插入图片描述
发送成功

发送复杂邮件:
复杂邮件可以带有HTML文本和附件

// 创建一个复杂邮件 MimeMessage mimeMessage = javaMailSender.createMimeMessage(); // 使用MimeMessageHelper 其构造方法传入true代表允许上传文件 MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); // 邮件信息设置 // 设置标题 mimeMessageHelper.setSubject("【xx网】恭喜!注册成功!"); // 设置内容 可以带上HTML样式 其构造方法传入true代表开启识别HTML标签 mimeMessageHelper.setText("您在xx网刚刚注册了一个账户,接下来您可以尽情使用了。",true); // 设置发送目的地邮箱地址 mimeMessageHelper.setTo("2222222222@qq.com"); // 设置发送者邮箱地址 mimeMessageHelper.setFrom("1111111111@qq.com"); // 上传附件 addAttachment(文件名,文件(可以是File或流之类的)) mimeMessageHelper.addAttachment("1.png",new File("F:\\IdeaProjects\\filetest\\img.png")); mimeMessageHelper.addAttachment("2.jpg",new File("F:\\IdeaProjects\\filetest\\img2.jpg")); // 发送邮件 javaMailSender.send(mimeMessage);

在这里插入图片描述
发送成功


作者:Piconjo_Official



part springboot mail async

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章