SpringBoot 结合 Quartz 简单Demo

首先,废话两句楼主是在开发中遇到具体需求,要用到定时器,那么大致说下两种定时器:

定时器 Quartz TimerTask
执行时间 可以通过cron表达式精确到特定时间执行 TimerTask不能
效率 每次执行任务都创建一个新的任务类对象 每次使用同一个任务类对象
对异常的处理 不会因为异常,而导致定时器关闭,不再执行循环任务。 抛出异常后,再也没有执行此任务了,并且定时器所在的线程也自动结束
消耗内存 大于TimerTask 小于Quartz
使用 整合使用,使用简单。 一旦出现异常,需要在异常的时候重构事务,需要工厂模式and代理模式的加入。

可以根据自己的水平 and 需求选择一个合适自己的上手。下面我们上干货。

PS:Quartz 会产生内存溢出的问题,楼主还没有仔细研究,有兴趣的同学可以研究下,欢迎给我的邮箱([email protected])发邮件一起探讨。

开发环境:Spring boot + Maven + mybatis 。

开发工具:idea

① 那么我们首先看需要的包,先看看pom.xml文件:

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency><!-- 该依赖必加,里面有sping对schedule的支持 -->
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

我只截取了部分,除了这些以外,如果你是spring boot 的项目一定还要有相关配置文件,别指望我会贴出来,做梦!摔!

② 先写一个监听器保证项目启动的时候会调用到,我们的定时任务,代码如下:

package task;

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

/**
* @author Lucky
* @Description 监听器
* @Date 15:08 2018/5/23
* @Param
* @return
**/
@Configuration
public class SchedulerListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    public MyScheduler myScheduler;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
            myScheduler.scheduleJobs();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        return schedulerFactoryBean;
    }
}

③ 写我们自己的定时器,用来触发我们的任务:

package task;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
/**
* @author Lucky
* @Description 
* @Date 13:48 2018/5/16
* @Param 
* @return 
**/
@Component
public class MyScheduler {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    static Scheduler scheduler;

    public void scheduleJobs() throws SchedulerException {
        scheduler = schedulerFactoryBean.getScheduler();
        startJob1(); // 每5分钟执行一次
        startJob2(); // 每2分钟执行一次
    }

    public static void startJob1() throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class).withIdentity("job1", "group1").build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
    public static void modifyJob1(String cron) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey("trigger1", "group1");
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        CronTrigger newTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.rescheduleJob(triggerKey, newTrigger);
    }
    public static String getJob1Status() throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey("trigger1", "group1");
        return scheduler.getTriggerState(triggerKey).name();
    }
    public static void pauseJob1() throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey("job1", "group1"));
    }
    public static void resumeJob1() throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey("job1", "group1"));
    }

    private void startJob2() throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class).withIdentity("job2", "group1").build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
    public static void modifyJob2(String cron) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey("trigger2", "group1");
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        CronTrigger newTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.rescheduleJob(triggerKey, newTrigger);
    }
    public static String getJob2Status() throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey("trigger2", "group1");
        return scheduler.getTriggerState(triggerKey).name();
    }
    public static void pauseJob2() throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey("job2", "group1"));
    }
    public static void resumeJob2() throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey("job2", "group1"));
    }

}

④ 接下来就写我们具体的任务如下:
第一个定时任务

package task;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;

/**
 * @ClassName ScheduledJob
 * @Description TODO
 * @Author Lucky
 * @Date 2018/5/16 13:46
 * @Version 1.0
 */
public class ScheduledJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("第一个定时任务" + new Date());
    }
}

第二个定时任务

package task;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;

/**
 * @ClassName ScheduledJob2
 * @Description TODO
 * @Author Lucky
 * @Date 2018/5/16 13:47
 * @Version 1.0
 */
public class ScheduledJob2 implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("第二个定时任务" + new Date());
    }
}

启动测试Demo(启动方法main直接写在了Controller里面,配个spring boot 注解@SpringBootApplication):

package task;

import org.quartz.SchedulerException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
* @author Lucky
* @Description 测试定时任务,启动类
* @Date 15:12 2018/5/23
* @Param
* @return
**/
@RestController
@SpringBootApplication
public class ScheduleController {

    @RequestMapping("/modify")
    public @ResponseBody String modify() throws SchedulerException {
        MyScheduler.modifyJob1("0/1 * * * * ?");
        return "1";
    }

    @RequestMapping("/status")
    public @ResponseBody String status() throws SchedulerException {
        return MyScheduler.getJob1Status();
    }

    @RequestMapping("/pause")
    public @ResponseBody String pause() throws SchedulerException {
        MyScheduler.pauseJob1();
        return "1";
    }

    @RequestMapping("/resume")
    public @ResponseBody String resume() throws SchedulerException {
        MyScheduler.resumeJob1();
        return "1";
    }

    public static void main(String[] args) {
        SpringApplication.run(ScheduleController.class, args);
    }
}

如果你在定时任务里,涉及到业务逻辑,需要查表用到service的对象,如果你直接在任务类里面通过注解的方式注入,比如:

    @Autowired
    private TestService service;

你会发现全部都是java.lang.NullPointerException,
那么怎么解决看这里,

我爱你
后来光阴单薄
年月时日都从肩头剥落
你当然可以忘记我
可答应我别忘记那年盛夏
我们哭着拥抱
承诺彼此
再也不难过

猜你喜欢

转载自blog.csdn.net/shasiqq/article/details/80421479