Springboot集成Quartz完成定时任务

一.Quartz的介绍和使用思路:

1.介绍:
    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
    Quartz是一个完全由java编写的开源作业调度框架。不要让作业调度这个术语吓着你。尽管Quartz框架整合了许多额外功能, 但就其简易形式看,你会发现它易用得简直让人受不了!。简单地创建一个实现org.quartz.Job接口的java类。Job接口包含唯一的方法:
public void execute(JobExecutionContext context)
throws JobExecutionException;
在你的Job接口实现类里面,添加一些逻辑到execute()方法。一旦你配置好Job实现类并设定好调度时间表,Quartz将密切注意剩余时间。当调度程序确定该是通知你的作业的时候,Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情。无需报告任何东西给调度器或调用任何特定的东西。仅仅执行任务和结束任务即可。如果配置你的作业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。

2.Quartz使用思路:

1). job - 任务 - 你要做什么事?
2). Trigger - 触发器 - 你什么时候去做?
3). Scheduler - 任务调度 - 你什么时候需要做什么事?

示例:

2.1 添加依赖:

<!--quarts依赖 并且去掉其带的slf4j依赖-->
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.2.1</version>
	<exclusions>
		<exclusion>
			<artifactId>slf4j-api</artifactId>
			<groupId>org.slf4j</groupId>
		</exclusion>
	</exclusions>
</dependency>
<!--添加Scheduled坐标-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
</dependency>
<!--Spring tx 坐标-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
</dependency>

2.2 首先要创建执行什么任务的类也就是Job类:

 /**
  * 定义任务类
  *
  * Created by ${ligh} on 2019/1/25 下午4:02
  */
  public class QuartzDemo implements Job {

  /**
   *  任务被触发时所执行的方法
   *
   * @param context
   * @throws JobExecutionException
   */
  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
      System.out.println("Execute ... " + new Date());
  }
}

2.3 使用Quartz来调度任务:

/**
 * Created by ${ligh} on 2019/1/25 下午4:09
 */
public class TestQuartz {

    public static void main(String[] args) throws Exception{

        //1.创建Job对象: 你要做什么事?
        JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();  //需要传入任务类的方法,就是做什么的类

        //2.创建Trigger对象,在什么时间做?
        /**
         * 简单的trigger触发时间: 通过Quartz提供一个方法来完成简单的重复调用
         *
         *  cron Trigger : 按照Cron的时间表达式给定触发的时间
         *
         */

        //下面采用通过Quartz提供的方法来执行,每秒钟执行一次,并且一直执行
//        Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatMinutelyForever())
//                .build();// 所需的参数就是给定的时间

        //下面是通过Cron表达式来控制时间, 没两秒执行一次
        Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();// 所需的参数就是给定的时间

        //3.创建Scheduler对象,整合上面两步,在什么时间做什么事?
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //把job和trigger交给Scheduler来调度
        scheduler.scheduleJob(job,trigger);

        //4.启动
        scheduler.start();
    }
}

测试结果:
在这里插入图片描述
二.Springboot整合Quartz定时框架:

第一步: 添加坐标

<!--quarts依赖 并且去掉其带的slf4j依赖-->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>
<!--添加Scheduled坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>
<!--Spring tx 坐标-->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>

第二步:简单实践

2.1 在quartz包中创建Job任务:

/**
  * 定义任务类
  *
  * Created by ${ligh} on 2019/1/25 下午4:02
  */
 public class QuartzDemo implements Job {
     /**
      *  任务被触发时所执行的方法
      *
      * @param context
      * @throws JobExecutionException
      */
     @Override
     public void execute(JobExecutionContext context) throws JobExecutionException {
         System.out.println("Execute ... " + new Date());
     }
 }

2.2 在config包下创建Quartz的配置类:

import com.ligh.quartz.QuartzDemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
/**
 *
 * Quartz的配置类
 *
 * Created by ${ligh} on 2019/1/25 下午5:28
 */
@Configuration
public class QuartzConfig {

    /**
     *  1.创建job对象  做什么
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        //关联自己的job类
        factory.setJobClass(QuartzDemo.class);
        return factory;
    }
    /**
     *  2.创建Trigger对象  什么时候做
     *
     *  简单Trigger
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
        //关联JobDetail对象
        factory.setJobDetail(jobDetailFactoryBean.getObject());
        //设置触发时间 该参数表示毫秒,2000表示2秒
        factory.setRepeatInterval(2000);
        //设置重复次数
        factory.setRepeatCount(5);
        return factory;
    }
    /**
     *  3.创建Scheduler对象
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        //关联trigger
        factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
        return factoryBean;
    }
}

2.3 修改启动类:

在启动类的上面加上@EnableScheduling注解,扫描Scheduler,不然启动会报错
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class QuartsApplication {
	public static void main(String[] args) {
		SpringApplication.run(QuartsApplication.class, args);
	}
}

拓展: 使用复杂的Cron表达式做定时任务(上面是简单的定时)

@Configuration
public class QuartzConfig {
    /**
     *  1.创建job对象  做什么
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        //关联自己的job类
        factory.setJobClass(QuartzDemo.class);
        return factory;
    }
    /**
     *  Cron Trigger
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
        //关联JobDetail
        factory.setJobDetail(jobDetailFactoryBean.getObject());
       //                             秒   分钟 小时 天 月 星期
        factory.setCronExpression("10,15,20 34 11 * * ?");
        //表示每年每月每天的11点34分的10,15,20秒都会执行一次
        return factory;
    }

    /**
     *  3.创建Scheduler对象
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean){
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        //关联trigger
        factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
        return factoryBean;
    }
}

三.任务类(Job)中注入对象:

    直接注入想要实现的业务逻辑的service是注入不进去的,所以要单独的编写一个类来将实现类注入到IOC容器中。
另外需要把该类传给Scheduler,在Scheduler中重新设置Job

注入不进去的原因:
    实例化QuartzConfig类时,并没有通过Spring,所以也不会去容器中去读取对应的service实现类,所以可以通过重写createJobInstance方法即可

3.1 定义业务逻辑实现:

@Service
public class UserServiceImpl implements UserService{
    @Override
    public void insertUser() {
        System.out.println("insert user method...");
    }
}

3.2 Job类的修改:

/**
 * 定义任务类
 * Created by ${ligh} on 2019/1/25 下午4:02
 */
public class QuartzDemo implements Job {

    @Autowired
    private UserService userService;

    /**
     *  任务被触发时所执行的方法
     *
     * @param context
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Execute ... " + new Date());
        userService.insertUser();
    }
}

3.3 创建一个类继承AdaptableJobFactory类,并重写createJobInstance方法

@Component
public class MyDaaptableJobFactory extends AdaptableJobFactory{

    //AutowireCapableBeanFactory 可以将一个对象添加到Spring的IOC容器中,并且完成该对象的注入
    @Autowired
    private AutowireCapableBeanFactory autowiredCaptableBeanFactory;
    /**
     *  该方法需要将实例化的任务对象手动的添加到Spring的IOC容器中,并且完成对象的注入
     *
     * @param bundle
     * @return
     * @throws Exception
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object o = super.createJobInstance(bundle);
        //将o对象添加到springIOC容器中,并完成注入
        autowiredCaptableBeanFactory.autowireBean(o);
        return o;
    }
}

3.4 修改QuartzConfig类中的Scheduler:

/**
  *  3.创建Scheduler对象
  */
 @Bean
 public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyDaptableJobFactory myDaptableJobFactory){
     SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
     //关联trigger
     factoryBean.setTriggers(cronTriggerFactoryBean.getObject());

     //传入新创建的类,不然service实现类注入不进去
     factoryBean.setJobFactory(myDaptableJobFactory);

     return factoryBean;
 }

测试结果展示:
在这里插入图片描述
以上就完成了Springboot集成Quartz定时任务的demo,希望有助于大家的学习。

猜你喜欢

转载自blog.csdn.net/ligh_sqh/article/details/86678735