Spring 和 Quartz 实现定时功能

Spring 和 Quartz 实现定时功能

在 pom.xml 中添加必须的包:

<!-- QuartzJobBean in spring-context-support.jar -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
</dependency>       

<!-- Spring + Quartz need transaction -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
</dependency>

<!-- Quartz framework -->
<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
</dependency>

首先要了解几个核心的概念:
Job:定时器要执行的任务;
JobDetail:定义任务的描述信息;
Trigger:定义任务如何执行,比如间隔多久,执行次数等;
Scheduler:管理任务的执行。

定义 Job——实现 Job 接口

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleJob implements Job {
    private static Logger logger = LoggerFactory.getLogger(SimpleJob.class);

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        Trigger trigger = jobExecutionContext.getTrigger();
        logger.info("execute {} with trigger: {}", jobDetail.getKey().getName(), 
                    trigger.getDescription());
    }
}

xml 配置:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- 定义 JobDetail -->
    <bean name="runJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.example.job.SimpleJob"/>
        <property name="name" value="mySimpleJob"/>
    </bean>

    <!-- 定义 SimpleTrigger 每隔5秒执行一次  -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="runJobDetail"/>
        <property name="repeatInterval" value="5000"/>
        <property name="startDelay" value="1000"/>
        <property name="description" value="mySimpleTrigger"/>
    </bean>

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger"/>
            </list>
        </property>
    </bean>

</beans>

Java 配置:

@Configuration
public class SpringJobConfig {

    @Bean
    public JobDetailFactoryBean runJobDetail() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(SimpleJob.class);
        // 使用类名作为job名称
        jobDetailFactoryBean.setName(SimpleJob.class.getSimpleName());
        return jobDetailFactoryBean;
    }

    @Bean
    public SimpleTriggerFactoryBean simpleTrigger(JobDetail runJobDetail) {
        SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
        simpleTriggerFactoryBean.setJobDetail(runJobDetail);
        simpleTriggerFactoryBean.setRepeatInterval(5000);
        simpleTriggerFactoryBean.setStartDelay(1000);
        simpleTriggerFactoryBean.setDescription("mySimpleTrigger");
        return simpleTriggerFactoryBean;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(Trigger simpleTrigger) {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setTriggers(simpleTrigger);
        return schedulerFactoryBean;
    }
}

自定义 Job 以及 CronTrigger

定义要执行任务的类,不需要实现 Job 接口:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CustomJob {
    private static Logger logger = LoggerFactory.getLogger(CustomJob.class);

    public static void execute() {
        logger.info("execute CustomJob with static method");
    }

    public void run() {
        logger.info("execute CustomJob with non-static method");
    }
}

类的任何方法都可以作为定时任务执行,既可以指定静态方法,也可以指定非静态方法,需要用 MethodInvokingJobDetailFactoryBean 定义 JobDetail:

    <bean id="customJob" class="com.example.job.CustomJob"/>

    <bean id="customRunJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 使用 targetClass 的话,需要在 targetMethod 中指定静态方法 -->
<!--        <property name="targetClass" value="com.example.job.CustomJob"/>-->
<!--        <property name="targetMethod" value="execute"/>-->
        <!-- 使用 targetClass 的话,需要在 targetMethod 中指定静态方法 -->
        <property name="targetObject" ref="customJob"/>
        <property name="targetMethod" value="run"/>
    </bean>

    <!-- Cron Trigger, run every 5 seconds -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="customRunJobDetail"/>
        <property name="cronExpression" value="0/3 * * * * ?"/>
        <property name="description" value="myCronTrigger"/>
    </bean>

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger"/>
                <ref bean="cronTrigger"/>
            </list>
        </property>
    </bean>

java 配置:

    @Bean
    public MethodInvokingJobDetailFactoryBean customJobDetail(CustomJob customJob) {
        MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
        // 定义静态方法
//        jobDetailFactoryBean.setTargetClass(CustomJob.class);
        jobDetailFactoryBean.setTargetObject(customJob);
        jobDetailFactoryBean.setTargetMethod("run");
        jobDetailFactoryBean.setName(customJob.getClass().getSimpleName());
        return jobDetailFactoryBean;
    }

    @Bean
    public CronTriggerFactoryBean cronTrigger(JobDetail customJobDetail) {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(customJobDetail);
        cronTriggerFactoryBean.setCronExpression("0/3 * * * * ?");
        cronTriggerFactoryBean.setDescription("myCronTrigger");
        return cronTriggerFactoryBean;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(Trigger simpleTrigger, Trigger cronTrigger) {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setTriggers(simpleTrigger, cronTrigger);
        return schedulerFactoryBean;
    }

定义是否启动任务

在 xml 中无法自定义任务是否启动,只要在 SchedulerFactoryBean 添加了某个 Trigger,服务启动之后就会运行任务。

在 Java 中,可以通过判断配置文件中的配置,来决定是否要把某个 Trigger 添加到 SchedulerFactoryBean 中。

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(Trigger simpleTrigger, Trigger cronTrigger) {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        List<Trigger> triggerList = new ArrayList<>();

        if (jobSwitch.contains(simpleTrigger.getJobKey().getName() + "+on")) {
            triggerList.add(simpleTrigger);
        }
        if (jobSwitch.contains(cronTrigger.getJobKey().getName() + "+on")) {
            triggerList.add(cronTrigger);
        }
        schedulerFactoryBean.setTriggers(triggerList.toArray(new Trigger[0]));
        return schedulerFactoryBean;
    }

参考:
https://www.baeldung.com/spring-quartz-schedule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值