进阶SpringBoot之异步任务、邮件任务和定时执行任务
SpringBooot 创建 Web 项目
异步任务:
service 包下创建 AsyncService 类
@Async 异步方法
Thread.sleep(3000) 停止三秒,捕获异常
package com.demo.task.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
//异步
@Service
public class AsyncService {
//异步方法
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
//throw new RuntimeException(e);
e.printStackTrace();
}
System.out.println("数据正在处理");
}
}
controller 包下创建 AsyncController 类
自动装配 AsyncService
方法里调用 AsyncService 类里的 hello 方法,停止三秒
package com.demo.task.controller;
import com.demo.task.service.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AsyncController {
@Autowired
AsyncService asyncService;
@RequestMapping("/hello")
public String hello(){
asyncService.hello();
return "OK";
}
}
主程序添加 @EnableAsync 开启异步注解功能
package com.demo.task;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync //开启异步注解功能
@SpringBootApplication
public class TaskApplication {
public static void main(String[] args) {
SpringApplication.run(TaskApplication.class, args);
}
}
启动即可,记得地址加后缀
(加了注解后,实际上响应很快,页面很快出现,但程序执行过了三秒,就是输出的那句“数据正在处理”过了三秒出现)
邮件任务:
pom.xml 导入 spring-boot-starter-mail 的 jar 包
<!-- 导入javax.mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
拿 qq 邮箱举例,点击设置 -> 账号,下滑找到 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务
点击管理服务,获取到授权码
application.properties 配置邮箱信息:
#邮箱账号
spring.mail.username=xx@qq.com
#邮箱密码:授权码
spring.mail.password=xx
spring.mail.host=smtp.qq.com
#开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
测试类:
自动装配 JavaMailSenderImpl
new 一个 SimpleMailMessage,调用邮件相关信息
最后发送即可
package com.demo.task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
@SpringBootTest
class TaskApplicationTests {
@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads() {
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("邮件主题");
message.setText("文本内容");
message.setTo("xx@qq.com");
message.setFrom("xx@qq.com");
mailSender.send(message);
}
}
上述只是简单的邮件,复杂邮件如下:
createMimeMessage -> new MimeMessageHelper -> ... -> send
package com.demo.task;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import java.io.File;
@SpringBootTest
class TaskApplicationTests {
@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads2() throws MessagingException {
MimeMessage mimeMessage = mailSender.createMimeMessage();
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
helper.setSubject("邮件主题");
helper.setText("<p style='color:red'>文本内容</p>",true);
//附件
helper.addAttachment("1.jpg",new File("E:\\1.jpg"));
helper.setTo("xx@qq.com");
helper.setFrom("xx@qq.com");
mailSender.send(mimeMessage);
}
}
定时任务:
主程序类上添加一行 @EnableScheduling 开启定时功能
package com.demo.task;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync //开启异步注解功能
@EnableScheduling //开启定时功能的注解
@SpringBootApplication
public class TaskApplication {
public static void main(String[] args) {
SpringApplication.run(TaskApplication.class, args);
}
}
service 包下创建 ScheduledService 类:
方法上添加 @Scheduled 注解
package com.demo.task.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class ScheduledService {
//定时:在一个特定的时间执行程序
//core表达式: 秒 分 时 日 月 周几
// 0/2 14 13 ? * 1-5 每个月周一到周五13点14分,每隔两秒执行一次
@Scheduled(cron = "0 20 5 * * ?") //每天5点20分0秒执行方法
public void hello(){
System.out.println("hello");
}
}
查看 Scheduled 源码,提供了多种配置调度任务的方式
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
@Reflective
public @interface Scheduled {
String CRON_DISABLED = "-";
String cron() default "";
String zone() default "";
long fixedDelay() default -1L;
String fixedDelayString() default "";
long fixedRate() default -1L;
String fixedRateString() default "";
long initialDelay() default -1L;
String initialDelayString() default "";
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
String scheduler() default "";
}
Cron 在线表达式生成器
可以实现在线生成表达式