Quartz - 定时任务框架

Quartz - 定时任务框架

一、简介

​ 对于定时任务的调度,设置好出发时间的规则,以及相应的业务处理。

​ ex:30分钟后 提交订单

二、简单使用

​ 1.引入依赖

        <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

​ 2.编写自己的业务类实现Job接口

public class job implements Job {
//    实现Job接口 重写方法
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//    方法里实现自己的任务
//        可以通过jobExecutionContext来获取jobDetail的信息
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobKey key = jobDetail.getKey();
        System.out.println(key.getGroup());
        System.out.println(key.getName());
        System.out.println("Hello Quartz" + new Date());

    }
}

​ 3.新建类对定时任务的实现

​ 新建调度器 把配置好的触发器和包装好的任务放到调度器上

public class HelloQuartz {
    public static void main(String[] args) throws SchedulerException {
//        1.调度器Scheduler
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//        2.设置触发器 主要描述任务的触发时间规则
        SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(10).withIntervalInSeconds(5))
//                Calendar日历的一个子类  描述一个时间
                .endAt(new GregorianCalendar(2020, 8, 18, 16, 18, 30).getTime())
                .build();
//        3.JobDetail 对于我们任务类的包装
        JobDetail jobDetail = JobBuilder.newJob(job.class).withIdentity("job1", "group1").build();
//        4.把JobDetail 和 触发器 添加到调度器中
        scheduler.scheduleJob(jobDetail,trigger);
//        启动 调度器开始工作
        scheduler.start();


    }
}

三、核心类说明

​ Scheduler:调度器,所有的调度都是由他控制,是Quartz的大脑,管理所有的任务。

​ Job:任务,想定时执行的事情(定义所需的业务逻辑)。

​ JobDetail:基于Job,进一步的包装,主要是关联所需的Job,并为他指定更加详细的属性(名称、组)。

​ Trigger:触发器,可以指定给某任务,指定任务的触发机制。

四、Trigger(触发器)

4.1 SimpleTrigger

​ 上述简单使用中已使用过,不做过多的描述。

4.2 CronTrigger(重点)
4.2.1 测试案例

​ 只需要修改触发器 不需要设置起始和结束时间

​ 使用Cron表达式(秒 分 时 日 月 星期几)

​ *代表每秒 */2代表每两秒 ?代表不限定

public class cronTrigger {
    public static void main(String[] args) throws SchedulerException {
//        1.调度器Scheduler
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//        2.设置触发器 主要描述任务的触发时间规则
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(CronScheduleBuilder.cronSchedule("* * * 18 8 ?"))
                .build();
//        3.JobDetail 对于我们任务类的包装
        JobDetail jobDetail = JobBuilder.newJob(job.class).withIdentity("job1", "group1").build();
//        4.把JobDetail 和 触发器 添加到调度器中
        scheduler.scheduleJob(jobDetail,trigger);
//        启动 调度器开始工作
        scheduler.start();


    }
}
4.2.2 Cron表达式的组成

​ Cron表达式(秒 分 时 日 月 星期几)

​ 1为周日 2为周一

位置时间域允许值特殊值
10-59, - * /
20-59, - * /
30-23, - * /
4日期1-31, - * ? / L W
5月份1-12, - * /
6星期1-7, - * ? / L W #
7年份, - * /
4.2.3 Cron表达式的符号

​ *代表每秒 ?代表不限定

​ 2/2代表从2秒开始每两秒 */2代表每两秒

​ 2-10代表从2秒到10秒

​ 2,3,5,7代表指定2秒 3秒 5秒 7秒

​ L在日期上表示本月最后一天

​ L放在星期上表示本周的周六,也就是7 6L放在星期上表示本月最后一个周五

​ 10W放在日期上表示离10号最近的一个工作日 不能跨月

​ LW放在日期上表示本月的最后一个工作日

​ 5#2用在星期上表示本月的第二个周四

五、对于Quartz的整合

5.1 引入依赖
        <!--quartz的使用需要依赖于spring的支持-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <!--quartz的依赖 去掉自带的日志 Springboot中已经有了-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--spring的事务依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
		
5.2 编写Job类

​ 也就是自己要实现的业务代码 实现Job接口

public class QuartzDemo implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("execute()"+new Date());
    }
}
5.3 编写Quartz配置类

​ 对JobDetail(做什么) Trigger(什么时间做) Scheduler(什么时间做什么)的配置

@Configuration
public class QuartzConfig {
//    创建Job对象
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
//     关联我们自己的Job类
        jobDetailFactoryBean.setJobClass(QuartzDemo.class);
        return jobDetailFactoryBean;
    }

    创建简单Trigger对象
//    @Bean
//    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
//        SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
      关联JobDetail对象
//        simpleTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
      该参数为一个执行的毫秒数和次数
//        simpleTriggerFactoryBean.setRepeatInterval(2000);
//        simpleTriggerFactoryBean.setRepeatCount(10);
//        return simpleTriggerFactoryBean;
//    }

//    创建CronTrigger对象
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        cronTriggerFactoryBean.setCronExpression("* * * * * ?");
        return cronTriggerFactoryBean;
    }
//    创建Scheduler对象
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean simpleTriggerFactoryBean){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
//        关联Trigger对象
        schedulerFactoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
        return schedulerFactoryBean;
    }


}
5.4 修改启动类

​ SpringBoot默认不开启定时任务 在启动类上添加@EnableScheduling注解开启

5.5 整合出现的问题

​ Job类注入其他类时候出现空指针异常

​ 原因:Spring IOC机制要求注入的类和被注入的类都必须在IOC容器中,而Job类的实例化则是在Quartz配置 类中,通过Quartz的AdaptableJobFactory类中的方法利用反射来实现的,所以需要重写此类的方 法,把返回的对象注入到IOC容器中。

@Component("myAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {
//  AutowireCapableBeanFactory 用于把对象放入IOC容器
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;
    @Override
    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
        Job job = super.newJob(bundle, scheduler);
//      把对象放入IOC容器
        this.autowireCapableBeanFactory.autowireBean(job);
        return job;
    }
}
//    创建Scheduler对象
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean simpleTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
//        关联Trigger对象
        schedulerFactoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
//        添加实例化后的JobFactory
        schedulerFactoryBean.setJobFactory(myAdaptableJobFactory);
        return schedulerFactoryBean;
    }

六、SpringBoot自带的定时任务

​ Scheduled定时任务器

6.1 引入依赖

使用Spring的依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
6.2 测试案例
@Component
public class ScheduledDemo {

//    定时任务方法
    @Scheduled(cron="* * * * * ?")
    public void scheduledMethed(){
        System.out.println(new Date());

    }
}

​ SpringBoot默认不开启定时任务 在启动类上添加@EnableScheduling注解开启

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值