Quartz 回顾小记

Quartz 回顾小记

Scroll Down

一、Quartz 基本使用

1. Quartz是一个任务调度框架,里面有几大核心对象

  • Job:接口,我们需要执行的定时任务需要实现的一个基本接口,只有一个execute方法。
public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext)
            throws JobExecutionException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date();
        System.out.println("Hello world\tTime Now:" + simpleDateFormat.format(date));
    }
}
  • JobDetail:描述一个Job对象的包装类,通过JobBudilder的静态方法构建,描述我们要执行的定时任务的id,组以及要传入的data等信息,如下:
JobDetail jobDetail= JobBuilder.newJob(MyJob.class)
        .withIdentity("jb2","gp2")
        .withDescription("测试job")
        .storeDurably()
        .build();
  • Trigger:任务触发器,用于触发定时任务的开关,通过TriggerBuilder构建,可以为其添加描述信息,例如触发哪一个job,触发器的id和组等,以及何时启动,然后定时任务执行多少次,间隔为多少等。如下(常用的有两种SimpleTrigger和CronTrigger):
Trigger trigger= TriggerBuilder
        .newTrigger()
        .forJob(jobDetail)   //为上面的任务对象构建
        .startNow()          //直接启动
        .withIdentity("tr1")        //id
        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .repeatForever()          //一直进行
                .withIntervalInMinutes(1))       //间隔为1分钟
        .build();
      
  • SchedulerFactory:调度器工厂,用于获取调度器,这是一个超级重要的对象,因为需要使用它来进行全局配置。
SchedulerFactory schedulerFactory=new StdSchedulerFactory();
Scheduler scheduler=schedulerFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
//即刻开始执行定时任务
  • JobStore :任务调度相关的存储,在我们启动程序的时候,程序会从classpath下面寻找Quartz的一个属性文件(quartz.properties),如果我们只进行上面的编码,则会因为找不到而进入Quartz的jar包中找到默认的配置文件,使用RAM进行信息存储(一般来说JobStore有两种配置,一是使用RAM的 RAMJobStore类 ,一是使用JDBC连接数据库的,常用 JobStoreTX 类),配置文件如下(更详细的详见官网):
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
org.quartz.scheduler.instanceName:DefaultQuartzScheduler
org.quartz.scheduler.rmi.export:false
org.quartz.scheduler.rmi.proxy:false
org.quartz.scheduler.wrapJobExecutionInUserTransaction:false
#线程池配置
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount:10
org.quartz.threadPool.threadPriority:5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread:true
org.quartz.jobStore.misfireThreshold:60000
#使用JDBC类的JobStore
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
#使用数据库代理类
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#数据库中存储调度信息的数据表前缀
#注意,数据表需要去官网下载给出的表样板
org.quartz.jobStore.tablePrefix=QRTZ_
#数据源配置
org.quartz.jobStore.dataSource=qzDS
org.quartz.dataSource.qzDS.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.qzDS.URL=jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.qzDS.user=user
org.quartz.dataSource.qzDS.password=password
org.quartz.dataSource.qzDS.maxConnections=10
  • 其它:JobDataMap用于向实现Job接口的对象传递数据,TriggerListener和JobListener用于监听任务的触发以及执行情况等,还有调度器的listener等

2. 完整代码示例(无属性文件版)

//Job对象
public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext)
            throws JobExecutionException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date();
        System.out.println("Hello world\tTime Now:" + simpleDateFormat.format(date));
    }
}
//主类
public class Main
{
    public static void main(String[]args) throws SchedulerException {
        JobDetail jobDetail= JobBuilder.newJob(MyJob.class)
                .withIdentity("jb2","gp2")
                .withDescription("测试job")
                .storeDurably()
                .build();

        Trigger trigger= TriggerBuilder
                .newTrigger()
                .forJob(jobDetail)
                .startNow()
                .withIdentity("tr1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .repeatForever()
                        .withIntervalInMinutes(1))
                .build();
                
        SchedulerFactory schedulerFactory=new StdSchedulerFactory();
        Scheduler scheduler=schedulerFactory.getScheduler();
        scheduler.start();
        scheduler.scheduleJob(jobDetail,trigger);
    }
}
  1. 使用持久化的任务调度(在2中的例子的classpath之下放入quartz.peoperties属性文件即可,但是注意配置数据源,线程池、JobStore类以及表数据库建表等。
  2. 建表sql文件---sql文件

二、Quartz 整合到 SSM

  1. 先创建 Maven 项目,引入 SSM 所需的 jar 包和 quartz 的 jar 包。
  2. 搭建SSM框架,即创建a pplicationContext.xml 、Dispacter-servlet.xml 等文件,配置 web.xml 等。
  3. 在 classpath 之下新增 quartz.xml 和 quartz.peoperties 两个文件。并将 quartz.xml 文件引入 IOC 容器(通过导入到 applicationContext.xml 或者在 web.xml 中配置为配置文件)
  4. 首先配置 quartz.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     
    <!--线程池bean的创建-->
    <bean id="pool" class="org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor">
        <property name="threadPriority" value="5"/>
        <property name="threadCount" value="10"/>
    </bean>

    <!--调度器工厂-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

        <!--指定quartz配置文件-->
        <property name="configLocation" value="classpath:quartz.properties"/>
         <!--配置线程池-->
        <property name="taskExecutor" ref="pool"/>
        <!--配置调度器名字,运行后,在数据库中能看到-->
        <property name="schedulerName" value="myScheduler"/>
        <property name="autoStartup" value="true"/>
    </bean>

quartz.peoperties配置内容详见Quartz基础小记部分。

  1. 创建一个Controller,以及一个处理器方法,并直接在控制器中注入一个调度器,以便使用(直接通过我们配置的调度器工厂获得):
//Job类
public class AJob implements Job
{
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println("哈哈");
    }
}

//控制器
@Controller
@RequestMapping(value = "/test")
public class Controller
{
    @Autowired
    private Scheduler scheduler;
    @GetMapping(value = "/test01")
    public void test() throws SchedulerException
    {
        System.out.println("访问");
        JobDetail jobDetail= JobBuilder.newJob(AJob.class)
                .withDescription("新测试")
                .withIdentity("jd1","gp1")
                .build();

        Trigger trigger= TriggerBuilder
                .newTrigger()
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()    
                        .withIntervalInMinutes(1)  //间隔一分钟
                .repeatForever())   //一直重复
                .forJob(jobDetail)
                .startNow()
                .withIdentity("t1","tp1")
                .startNow()
                .build();
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }
}
  1. 使用开发工具执行quartz的建表sql文件。
  2. 然后访问控制器,即可看到控制台会输出job实现类定义的语句,并且循环执行,打开Navicat可以看到数据表中有相关的任务信息等。
  3. 总结:
  • 主要就是定义SchedulerFactoryBean,为它指定配置文件等
  • 注意数据库等方面的配置即可,然后在需要的地方注入
  1. ,,,,,,