本文纯个人读书笔记,书籍《一步一步学 Spring Boot 2》
如果喜欢,可直接购买书籍。如有侵权,请联系删除
Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。
Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
Quartz 允许程序开发人员根据时间的间隔来调度作业。
Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。
Quartz框架主要核心组件包括调度器、触发器、作业。
Job: 表示一个工作,要执行的具体内容。Job 接口中只有一个方法 execute,JobExecutionContext 类提供了调度上下文的各种信息。每次执行该 Job 都会重新创建一个 Job 实例。
void execute(JobExecutionContext context)
JobDetail: 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。 Quartz 在实际上接收的是 Job 实现类,运行时通过 newInstance() 的反射机制实例化 Job。因此需要通过一个类来描述 Job 的实现类及其它相关的静态信息,如 Job 名字、描述、关联监听器等信息,JobDetail 承担了这一角色。JobDetail 用来保存我们作业的详细信息。一个 JobDetail 可以有多个Trigger,但是一个 Trigger 只能对应一个 JobDetail。
Trigger: 代表一个调度参数的配置,什么时候去调。主要有 SimpleTrigger 和 CronTrigger 这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger 是最适合的选择;而 CronTrigger 则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案:如每早晨 9:00 执行,周一、周三、周五下午 5:00 执行等。
CronTrigger 配置格式:
格式: [秒] [分] [小时] [日] [月] [周] [年]
0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)
Scheduler: 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。Scheduler 使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。
在 pom 文件中添加 Quartz 的依赖。
pom.xml:
org.quartz-scheduler
quartz
2.2.3
创建 Quartz 定时器有两种方法:1.使用 XML 配置文件的方式。2.使用注解的方式。 这边先介绍使用注解的方式。
1.定时器类
编写一个定时器类 com.xiaoyue.demo.quartz.TestTask。
TestTask:
public class TestTask {
//日志对象
private static final Logger logger = LogManager.getLogger(TestTask.class);
public void run() {
logger.info("定时器运行了!!!");
}
}
2.配置文件
在 /src/main/resources 目录下新建配置文件 spring-mvc.xml。
spring-mvc.xml:
利用 import 标签导入定时器的配置文件,该标签可以根据具体业务分离配置文件。我们需要在在 /src/main/resources 目录下新建对应的配置文件 spring-quartz.xml。
spring-quartz.xml:
run
0/10 * * * * ?
3.加载配置文件
我们在上面新增了 spring-mvc.xml,这个配置文件需要我们手动去加载才可以。修改启动类 DemoApplication。
DemoApplication.java:
@SpringBootApplication
@ServletComponentScan
@ImportResource(locations={"classpath:spring-mvc.xml"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
使用注解进行定时器的开发相对来说比较简单,只需要配置注解就可以了。
TestTask :
@Component
@Configurable
@EnableScheduling
public class TestTask {
//日志对象
private static final Logger logger = LogManager.getLogger(TestTask.class);
//每5秒执行一次
@Scheduled(cron = "*/10 * * * * * ")
public void run() {
logger.info("定时器运行了!!!");
}
}
实际应用中,发送邮件的需求比较常见,如找回密码、事件通知等。邮件发送与接收的过程如下:
1.发件人使用 SMTP 协议传输邮件到邮件服务器 A;
2.邮件服务器 A 根据邮件中指定的接收者,投送邮件至相应的邮件服务器 B;
3.收件人使用 POP3 协议从邮件服务器 B 接收邮件。
SMTP(Simple Mail Transfer Protocol)是电子邮件(Email)传输的互联网标准,定义在 RFC5321,默认使用端口 25;
POP3(Post Office Protocol - Version 3)主要用于支持使用客户端远程管理在服务器上的电子邮件。定义在 RFC 1939,为 POP 协议的第三版(最新版)。
这两个协议均属于 TCP/IP 协议族的应用层协议,运行在 TCP 层之上。
SUN 公司提供了一款邮件发送和接收的开源类库 JavaMail,支持常用的邮件协议:SMTP、POP3、IMAP等。使用 JavaMail 编写邮件程序时,不再需要考虑底层的通讯细节。JavaMail可以发送各种复杂 MIME 格式的邮件内容, JavaMail 仅支持 JDK4 及以上版本。虽然 JavaMail 是 JDK 的 API 但它并没有直接加入 JDK 中,所以我们需要另外添加依赖。
Spring 提供了非常好用的 JavaMailSender 接口实现邮件发送。在 Spring Boot 的 Starter 模块中已为此提供了自动化配置。
在 pom.xml 中添加发送邮件的依赖。
pom.xml:
org.springframework.boot
spring-boot-starter-mail
###mail邮件配置
###邮箱主机
spring.mail.host=smtp.163.com
###用户名
spring.mail.username=邮箱
###设置的授权码
spring.mail.password=授权码
###默认编码
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
新建发送邮件接口 com.xiaoyue.demo.mail.SendMailService。
SendMailService:
public interface SendMailService {
boolean sendMail();
}
新建接口实现类 com.xiaoyue.demo.mail.impl.SendMailServiceImpl。
SendMailServiceImpl:
@Service
public class SendMailServiceImpl implements SendMailService {
@Autowired
JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
public static final Logger logger =
LogManager.getLogger(SendMailServiceImpl.class);
@Override
public boolean sendMail() {
try{
MimeMessage mimeMessage = this.mailSender.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
//邮件发送方
message.setFrom(from);
//邮件主题
message.setSubject("会议通知");
//邮件接收方
message.setTo("[email protected]");
//邮件内容
message.setText("明天早上 9 点开会,请准时到达");
//发送邮件
this.mailSender.send(mimeMessage);
}catch(Exception ex){
logger.error("sendMail error ", ex);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
注: 由于 163 邮箱的反垃圾邮件机制,测试这个的时候,先把收件人写成自己进行测试,其他发送邮件问题,这边不进行过多讲解。
在测试类 DemoApplicationTests 中添加测试代码进行测试。
DemoApplicationTests:
@Resource
private SendMailService sendMailService;
@Test
public void testSendMai(){
sendMailService.sendMail();
}
登录 163 邮箱进行查看。