SpringBoot整合定时任务 Schedule定时任务器和Quartz定时任务框架

定时器:

在一定时间内执行的所触发的方法。使用场景也挺多的,如一个系统的日志需要定期删除。

Schedule:

定时任务器:是spirng3.0以后自带的一个定时任务器。

使用:

第一步:在pom文件中添加schedule的坐标

         <!--spring-boot的核心启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--添加Schedule定时器-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <!--开启test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

第二步:添加ScheduleDemo测试类

@Component
public class ScheduleDemo {

    /**
     * 定时任务
     * @Scheduled 设置定时任务
     * cron 需要cron的表达式 是一个定时触发的字符串的表达式
     *
     * cron表达式
     * 分6字表达式和7字表达式
     *
     * second minute hour day month week 6字表达式
     * second minute hour day month week year 7字表达式
     *
     * second 区间 [0,59]
     * minute 区间 [0,59]
     * hour 区间 [0,23]
     * day 区间 [1,31]
     * month 区间 [1,12]
     * week 区间 [1,7],注意 这里星期一代表7,星期填为6,外国的第一天是从7开始
     * year 区间[1950,2099]
     *
     * 符号的作用:
     * 1.星号(*):可用在所有字段中,代表对应时间的每一刻,eg:*在分钟字段中代表,每一分钟执行
     * 2.问号(?):占位符作用,通常指定无意义的值
     * 3.减号(-):代表一个区间,表示在一个时间范围之内 10-12
     * 4.逗号(,) 代表在一个范围内,1,4,5,6 在此序列内
     * 5.斜杠(/):x/y代表一个等长序列,x为起始值,y为递增步数,0/15,若在秒中出现则是每隔15秒执行一次
     * 等。
     *
     * eg:@Scheduled(cron = "0 0 1 1 1,4,7,10 ?")//每个季度的一月一号1点执行
     *
     */
    @Scheduled(cron = "0/2 * * * * ?")
    public void scheduleMethod(){

        System.out.println("触发 "+ new Date());

    }

}

第三步:在启动类中开启定时任务

@SpringBootApplication
@EnableScheduling//开启schedule定时任务
public class App extends SpringBootServletInitializer {
    
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(App.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

Quartz:

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。

使用:

1.Job-任务 你要做什么事情

2.Trigger-触发器 什么时候去做

3.Schedule 任务调度 你什么时候去做什么事情.

第一步:在pom文件中添加Quartz的坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.whut.schedule</groupId>
    <artifactId>spring-boot-schedule</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--spring-boot的核心启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--添加Schedule定时器-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <!--开启test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--Quartz的坐标-->
        <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>

        <!--Spring tx 坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

    </dependencies>
    
</project>

第二步:编写QuartzDemo任务类

/**
 * 定义任务类
 * 整合SpringBoot
 */
@Component
public class QuartzDemo implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("execute " + new Date());
    }
}

第三步:配置Quartz,编写QuartzConfig类来配置Quartz

@Configuration
public class QuartzConfig {
    /**
     * 创建Job对象
     *要去做什么
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){

        JobDetailFactoryBean factory = new JobDetailFactoryBean();

    
        factory.setJobClass(QuartzDemo.class);

        return factory;
    }

    /**
     * 创建Trigger对象
     * 什么时候去做
     * 创建的简单的Trigger
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){

        SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();

        //整合Job 关联Job
        //
        factory.setJobDetail(jobDetailFactoryBean.getObject());

        //repeatInterval 执行的毫秒数
        factory.setRepeatInterval(2000);

        //设置重复次数
        factory.setRepeatCount(5);

        return factory;
    }

    /**
     * CronTrigger
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factory = new CronTriggerFactoryBean();

        //关联Job
        factory.setJobDetail(jobDetailFactoryBean.getObject());

        //设置CronTrigger
        factory.setCronExpression("0/2 * * * * ?");

        return factory;
    }


    /**
     * 创建Scheduler对象
     * 在什么时间去做什么事情
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(
            SimpleTriggerFactoryBean simpleTriggerFactoryBean,
            MyAdaptableJobFactory myAdaptableJobFactory
            ){

        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        //关联Trigger 可以关联CronTrigger
        factory.setTriggers(simpleTriggerFactoryBean.getObject());


        return factory;
    }


}

经过上述操作即可完成定时任务的整合。

Quartz:Quartz整合业务逻辑对象的注入

上述都是在测试是否能正常在特定时间内执行定时触发任务,没有关联业务逻辑代码。

给定场景:在特定时间内添加用户,这里简单化处理

一:新建测试服务类UserService

@Service
public class UserService {

    public void addUser(){
        System.out.println("add user :" + new Date());
    }

}

二:在任务类QuartzDemo中注入该任务类

/**
 * 定义任务类
 * 整合SpringBoot
 */
@Component
public class QuartzDemo implements Job {

    @Autowired
    private UserService userService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("execute " + new Date());

        userService.addUser();
    }
}

当运行该项目时候会抛出这样的错误:

提示我们的UserService 没有注入进去。

原因:

QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成
* 实际上实例化采用反射机制来实现
* QuartzDemo 的实例化没有经过Spring的处理
* Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中

这里需要我们手动将对象注入到SpingIOC容器中.

三:添加MyAdaptableJobFactory来手动注入


@Component("myAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {


    //将一个对象加入到SpringIOC容器中,并且完成对象注入
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    /**
     * 将实列化的任务对象手动加入到SpringIOC容器中,并且完成对象注入
     * @param bundle
     * @return
     * @throws Exception
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

        Object object = super.createJobInstance(bundle);

        //将object添加到SpringIOC容器中,并完成对象的注入
        this.autowireCapableBeanFactory.autowireBean(object);

        return object;
    }
}

四:修改QuartzConfig来完成配置

@Configuration
public class QuartzConfig {
    /**
     * 创建Job对象
     *要去做什么
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){

        JobDetailFactoryBean factory = new JobDetailFactoryBean();

        /**
         * QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成
         * 实际上实例化采用反射机制来实现
         * QuartzDemo 的实例化没有经过Spring的处理
         * Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中
         */
        factory.setJobClass(QuartzDemo.class);

        return factory;
    }

    /**
     * 创建Trigger对象
     * 什么时候去做
     * 创建的简单的Trigger
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){

        SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();

        //整合Job 关联Job
        //
        factory.setJobDetail(jobDetailFactoryBean.getObject());

        //repeatInterval 执行的毫秒数
        factory.setRepeatInterval(2000);

        //设置重复次数
        factory.setRepeatCount(5);

        return factory;
    }

    /**
     * CronTrigger
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factory = new CronTriggerFactoryBean();

        //关联Job
        factory.setJobDetail(jobDetailFactoryBean.getObject());

        //设置CronTrigger
        factory.setCronExpression("0/2 * * * * ?");

        return factory;
    }


    /**
     * 创建Scheduler对象
     * 在什么时间去做什么事情
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(
            SimpleTriggerFactoryBean simpleTriggerFactoryBean,
            MyAdaptableJobFactory myAdaptableJobFactory
            ){

        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        //关联Trigger 可以关联CronTrigger
        factory.setTriggers(simpleTriggerFactoryBean.getObject());

        //手动注入
        //----------------------------------------------------------
        factory.setJobFactory(myAdaptableJobFactory);
        //----------------------------------------------------------
        
        return factory;
    }


}

这样就完成了业务逻辑的定时触发

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值