前言
本文是对之前的一篇文章Spring+SpringMVC+mybatis+Quartz整合代码部分做的一个修改和补充, 其中最大的变化就是后台框架变成了Spring Boot。
本工程所用到的技术或工具有:
- Spring Boot
- Mybatis
- Quartz
- PageHelper
- VueJS
- ElementUI
- MySql数据库
正文
配置
本例中仍然是使用mysql数据库作为Quartz任务持久化的存储载体。对于如何在Mysql数据库中建立表,在上一篇Spring+SpringMVC+mybatis+Quartz整合中已经有了详细的介绍。这里我们来看Spring Boot工程的建立方法。在Spring网站上有关于建立Spring Boot工程的脚手架,我们按如下图的方式设置,然后点击Generate Project即可。
接着我们在IDE中导入这个maven工程,然后可以看到src/main/resource下面有一个名字为application.properties的文件,里面的内容是空的。我们删除这个文件,然后在这个目录下新建一个名为application.yml的文件。这是配置Spring Boot工程的另一种方式,也是Spring Boot官方推荐的一种配置方式。我们在新建的这个yml文件中,加入如下代码
spring:
datasource:
url: jdbc:mysql://190.0.1.88:3306/hello_test?useUnicode=true
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations:
- classpath:com/example/demo/mapper/*.xml
type-aliases-package: com.example.demo.entity
上面的代码是对数据库和mybatis的一些配置。
接着我们在当前目录下再新建一个名为quartz.properties的文件。这是对Quartz的配置文件。加入如下代码:
# 固定前缀org.quartz
# 主要分为scheduler、threadPool、jobStore、plugin等部分
#
#
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# threadCount和threadPriority将以setter的形式注入ThreadPool实例
# 并发个数
org.quartz.threadPool.threadCount = 5
# 优先级
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 5000
# 默认存储在内存中
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
#持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS
org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://190.0.1.88:3306/hello_test?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = root
org.quartz.dataSource.qzDS.maxConnections = 10
可以看出和上一篇文章的配置文件完成相同。接着我们在com.example.demo下新建一个名为SchedulerConfig.java的文件。在这个文件里,对刚才我们新建的quartz.properties文件进行读取。
package com.example.demo;
import java.io.IOException;
import java.util.Properties;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerConfig {
@Bean(name="SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//在quartz.properties中的属性被读取并注入后再初始化对象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/*
* quartz初始化监听器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/*
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
注意最下方的QuartzInitializerListener。在SpringMVC中,我们在配置Quartz的时候,要在web.xml中加入如下配置:
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
这个监听器可以监听到工程的启动,在工程停止再启动时可以让已有的定时任务继续进行。由于我们目前的工程是Spring Boot,没有web.xml的配置方式,所以我们在上文的SchedulerConfig类中直接注入了这个Bean。
实现
先来看Job类。首先设置一个BaseJob接口,用来继承Job类:
package com.example.demo.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public interface BaseJob extends Job{
public void execute(JobExecutionContext context) throws JobExecutionException;
}
然后两个Job类用来实现BaseJob类:
HelloJob
package com.example.demo.job;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements BaseJob {
private static Logger _log = LoggerFactory.getLogger(HelloJob.class);
public HelloJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
_log.error("Hello Job执行时间: " +