quartz定时器,及与spring两种整合方式介绍

前言

最近正好用到定时器,这边顺便把定时器quartz做一个简单的总结。

添加依赖

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.2.1</version>
</dependency>
<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-jobs</artifactId>
  <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.2.6.RELEASE</version>
 </dependency>

上代码:

public static void simpleTrigger() {
        try {
            //创建工厂,获取调度器scheduler
            Scheduler scheduler = new StdSchedulerFactory().getScheduler();
            //构建jobBuilder
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("job", "group").build();
            //定义一个trigger
            SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger().withIdentity("trigger", "group").startNow().
            withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
            //加入调度
            scheduler.scheduleJob(jobDetail, simpleTrigger);
            //启动
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

自定义一个类实现Job接口,实现它的execute方法

public class MyJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("现在时间是"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

}

上面就是一个简单的定时器,每两秒执行一次MyJob中的execute方法

这个例子中包含几个重要的类:

  • Scheduler:调度器。所有的调度都是由它控制。
  • Trigger: 定义触发的条件。例子中,它的类型是SimpleTrigger,每隔2秒中执行一次
  • JobDetail :要执行的任务

trigger

SimpleTrigger:指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务

CronTrigger:指定从某一个时间开始,以一定的时间间隔执行的任务。 但是不同的是SimpleTrigger指定的时间间隔为毫秒,没办法指定每隔一个月执行一次(每月的时间间隔不是固定值),而CronTrigger支持的间隔单位有秒,分钟,小时,天,月,年,星期。相较于SimpleTrigger有两个优势:1、更方便,比如每隔1小时执行,你不用自己去计算1小时等于多少毫秒。 2、支持不是固定长度的间隔,比如间隔为月和年。但劣势是精度只能到秒。

CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("triger", "group")
                         .startNow().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();

这边时间执行参数“*,*,*,*,*,*,*”  [秒] [分] [小时] [日] [月] [周] [年] ,具体怎么写不多做阐述,百度上搜索“在线Cron表达式生成器”

整合spring

方式一:JobDetailFactoryBean

1.创建类实现Job接口

public class MyJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("现在时间是"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

}

 

2.xml实现

<bean id="jobFactory" class="com.cao.quartz.MyJobFactory"></bean>
    
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> 
  <!-- 指定具体的job类 -->
  <property name="jobClass" value="com.cao.quartz.MyJob"></property> </bean> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail" ></property> <property name="startDelay" value="3000"></property> <property name="repeatInterval" value="2000" ></property> </bean> <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
     <property name="jobFactory" ref="jobFactory"></property> <property name="triggers"> <list> <ref bean="simpleTrigger"/> </list> </property>
</bean>

 

3.解决注入Service为null的问题

定义一个JobFactory

public class JobFactory extends  org.springframework.scheduling.quartz.SpringBeanJobFactory{

    @Autowired

    private AutowireCapableBeanFactory beanFactory;

    @Override

    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

        Object jobInstance = super.createJobInstance(bundle);

        beanFactory.autowireBean(jobInstance);

        return jobInstance;

    }

}

接下来把他配置到Spring当中去

<bean id="jobFactory" class="com.cao.quartz.MyJobFactory"></bean>

然后在把org.springframework.scheduling.quartz.SchedulerFactoryBean的jobFactory设置成我们自己的。

<bean name="MyScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <!-- 其他属性省略 -->
  <property name="jobFactory" ref="jobFactory"></property>
</bean>

 

方式二.MethodInvokingJobDetailFactoryBean

1.定义一个方法,这边不需要实现Job接口

public class SpringJob {
    public void doSomething() {
        System.out.println("现在时间是"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

 

xml配置:

<!--执行的类  -->
    <bean id="testJob" class="com.cao.controller.TestQuartz" ></bean>
    
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
        <!--要执行的类 ,将上面的注入 -->
        <property name="targetObject" ref="testJob" ></property>
        <!-- 任务要执行的方法  -->
        <property name="targetMethod" value="doSomething"></property>
        <!-- 上一次未执行完成的,要等待有再执行。 -->
        <property name="concurrent" value="false"></property>
    </bean>
    
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <!--上面定义的jobDetail  -->
        <property name="jobDetail" ref="jobDetail" ></property>
        <property name="startDelay" value="3000"></property>
        <property name="repeatInterval" value="2000" ></property>
    </bean>
    
    <!--  <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
         <property name="jobDetail" ref="jobDetail"/>
         <property name="cronExpression" value="0/2 * * * * ?"/>
     </bean> -->
    
    <!--  总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
     <bean id="startQuertz" lazy-init="false" autowire="no" 
      class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
         <property name="triggers">
             <list>
                 <ref bean="simpleTrigger"/>
                 <!-- <ref bean="cronTrigger"/> -->
             </list>
         </property>
     </bean>

 


 

 

posted on 2018-07-09 15:57  随风1992  阅读(197)  评论(0编辑  收藏  举报

导航