场景1 当用户在前台页面使用邮件发送功能,这个请求会交于后端处理,如果采用同步任务,在这段时间内,前台的页面都是等待状态的,用户还会以为卡死,耗费时间和资源。
场景2用户上传Excel表格,后端需要先解析并且插入到数据库中,这个任务量是巨大的,所以这些均需要做异步处理。
......
以上这些场景使用多线程也是能解决的,这里简单记录一下,springBoot的异步使用方式。
异步任务在SpringBoot中开启异步任务很简单,两个注解搞定 @EnableAsync
与 Async
。这里简单写个案例
1、需要执行的异步方法
@Async //方法加上这个注解,SpringBoot会开启一个新的线程来处理,也就不会有白屏等待时间
public void insertExcel() {
// 假如这个方法中执行一段耗时的逻辑代码 比如excel表格的读取与插入
// 这里使用线程休眠来模拟,执行到这里,前台会白屏5秒
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据正在处理中...");
}
2、启动类开启异步注解功能
@EnableAsync //开启异步注解
@SpringBootApplication
@MapperScan("com.qd.springboot.mapper")
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
执行此方法后,控制台会直接打印内容,而无需等待时间,就是这么的香~
邮件任务发送邮件任务也是开发中经常使用的,在SpringBoot中也比较简单
1、导入依赖
<!--jakarta.mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.5.2</version>
</dependency>
2、查看官方配置类
3、调用的方法
4、配置邮箱部分,开启协议并且生成授权码
5、配置yml
spring:
mail:
username: 666@qq.com # 邮箱号
password: # 授权码
host: smtp.qq.com # 发送的服务器
properties: {mail.smtp.ssl.enable:true} # 开启安全验证 部分邮箱没有
6、简单邮箱实现
@SpringBootTest
public class Test1 {
@Autowired
private JavaMailSenderImpl mailSender;
/**
* 简单邮件
*/
@Test
public void sendMail01() {
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("java邮件测试"); //主题
message.setText("试搞一个ava的邮件发送测试,你能猜出我是谁吗???"); //内容
message.setTo("666@qq.com"); //接收人,是一个可变参数
message.setFrom("666@qq.com"); // 发送者,必须与配置文件中一致
message.setTo();
mailSender.send(message);
}
/**
* 复杂邮件
*/
@Test
public void sendMail02() throws MessagingException {
// 可以直接传入文件
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
helper.setSubject("java邮件测试");
String content = "内容";
helper.setText("<div style='width: 100%;min-height: 250px;background-color: rgb(227,242,253);'> <h2 style='text-align: center;color: rgb(187, 70, 70);'>xxx服务邮件通知</h2><div style='width: 100%;min-height: 150px;margin: 20px 0px;background-color: white;'><h3>尊敬的用户:</h3> <p style='padding: 0px 20px;'>" + content + "</p><p style='padding: 0px 20px;'>此致(本邮件由程序自动发送,您无需回复)</p></div><footer style='text-align: center;color: rgb(92, 96, 99);'><a href=\"#\">xxxx公司</a></footer></div>\n", true);
// helper.addAttachment("附件名",new File("附件地址"));
helper.setTo("666@qq.com");
helper.setFrom("666@qq.com");
mailSender.send(message);
}
}
ps:为了方便开发可以抽取成为工具类
定时任务在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作。比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量等。
在Spring Boot 中有Java自带的java.util.Timer类,也有强大的调度器Quartz,还有SpringBoot 自带的Scheduled 来实现。Scheduled在Spring5.引入,默认SpringBoot 自带该功能,使用起来也很简单,在启动类级别添加@EnableScheduling注解即可引入定时任务环境,但遗憾的是Scheduled 默认不支持分布式环境,这里简单测试下。
1、开启注解支持
@EnableScheduling // 开启注解支持
@SpringBootApplication
@MapperScan("com.qd.springboot.mapper")
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
2、cron表达式
// cron表达式
// cron = "0 * * * * 0-7"
// 秒 分 时 日 月 周几
在定时任务中,离不开这个表达式,不太好理解但是没关系 使用在线生成器 在线Cron表达式生成器
3、使用
@Service
public class ScheduledService {
/**
* 定时执行任务
* 每天的0点30分会自动执行
*/
@Scheduled(cron = "30 0 0 * * * *")
public void hello(){
System.out.println("在一个特定的时间里执行这个方法");
}
}
使用起来特别的简单,但是如果你的项目是分布式的话,你可以使用Quartz这个框架来执行,在SpringBoot整合中也有提到过。