Spring Quartz使用教程

7,907 阅读3分钟

1.Spring Quartz 使用教程

Quartz是一个企业级的定时任务调度框架,它使用JobJobDetailTrigger这三个主要部分来完成任务调度,目前Quartz在企业中使用的也比较多,Quartz官网。Spring为了简化Quartz在Spring的企业级应用程序中的使用,提供了4个主要的类:org.springframework.scheduling.quartz.QuartzJobBean org.springframework.scheduling.quartz.JobDetailFactoryBeanorg.springframework.scheduling.quartz.CronTriggerFactoryBeanorg.springframework.scheduling.quartz.SchedulerFactoryBean,其实就是对应了Quartz的三个部分,Spring Quartz官方文档

1.导入jar

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

2.基于xml配置

1.JobDetailFactoryBean

JobDetailFactoryBean是把某个类作为Job任务,这个类实现org.quartz.Job接口或者继承org.springframework.scheduling.quartz.QuartzJobBean即可。

Job类:

public class JobExample extends QuartzJobBean {

    /**
     * 这个申明的属性会被放在JobDetailFactoryBean的jobDataMap属性
     * 相当于开放了一个扩展的Map,供用户自定义属性
     */
    private int timeout;

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        //JobExecutionContext 包含了Job的所有信息
        //doSomething
    }
}

配置:

<!--JobDetail 这种方式是整个类作为Job任务-->
<bean id="jobDetailFactoryBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <!--指定Job-->
    <property name="jobClass" value="com.ly.quartz.JobExample"/>
    <!--扩展属性-->
    <property name="jobDataAsMap">
        <map>
            <entry key="timeout" value="5"/>
        </map>
    </property>
</bean>

2.MethodInvokingJobDetailFactoryBean

MethodInvokingJobDetailFactoryBean是可以指定某个类的某个具体的方法作为Job任务,只要IOC容器中管理这个类,那么就可以实现这种任务调用。

Job类:

public class ExampleBusinessObject {

    /**
     * method job
     * 可以出参和入参
     */
    public void doIt(String param) {
        //doSomething
    }
}

配置:

<!--Job Bean-->
<bean id="businessObject" class="com.ly.quartz.ExampleBusinessObject"/>
<!-- JobDetail
        仅仅指定某个对象的某个方法
        -->
<bean id="methodInvokingJobDetailFactoryBean"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <!--目标对象-->
    <property name="targetObject" ref="businessObject"/>
    <!--目标方法-->
    <property name="targetMethod" value="doIt"/>
    <!--方法参数-->
    <property name="arguments">
        <props>
            <prop key="param">param</prop>
        </props>
    </property>
    <!--默认是并发执行的,但是可能会导致一个job的结果影响另一个job的结果,因此我们一般设置false-->
    <property name="concurrent" value="false"/>
</bean>

3.配置Trigger和Scheduler

<!--SimpleTrigger-->
    <bean id="simpleTriggerFactoryBean" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetailFactoryBean"/>
        <!-- 10 s-->
        <property name="startDelay" value="10000"/>
        <!-- repeat every 50 seconds-->
        <property name="repeatInterval" value="50000"/>
    </bean>

    <!--CronTrigger-->
    <bean id="cronTriggerFactoryBean" 				    class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="methodInvokingJobDetailFactoryBean"/>
        <!-- cron expression: every day morning at 6 am-->
        <property name="cronExpression" value="* * 6 * * ?"/>
    </bean>

    <!--任务调度-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--触发器-->
        <property name="triggers">
            <list>
                <ref bean="simpleTriggerFactoryBean"/>
                <ref bean="cronTriggerFactoryBean"/>
            </list>
        </property>
        <!--允许覆盖已经存在的任务-->
        <property name="overwriteExistingJobs" value="true"/>
    </bean>

3.基于java config配置

@Configuration
public class QuartzConfig {

    /**
     * 整个类作为任务
     *
     * @return
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(JobExample.class);
        //扩展属性
        HashMap<String, Object> map = new HashMap<>();
        map.put("timeout", 1000);
        factoryBean.setJobDataAsMap(map);
        return factoryBean;
    }


    @Bean
    public ExampleBusinessObject bean() {
        return new ExampleBusinessObject();
    }
    
    /**
     * 某个对象的某个方法作为任务
     *
     * @return
     */
    @Bean
    public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean factoryBean = new MethodInvokingJobDetailFactoryBean();
        factoryBean.setTargetBeanName("exampleBusinessObject");
        factoryBean.setTargetMethod("doIt");
        factoryBean.setConcurrent(false);
        return factoryBean;
    }

    /**
     * cron expression
     *
     * @param jobDetailFactoryBean
     * @return
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
        CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        factoryBean.setCronExpression("* */1 * * ?");
        return factoryBean;
    }

    /**
     * simple trigger
     *
     * @param methodInvokingJobDetailFactoryBean
     * @return
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean) {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(methodInvokingJobDetailFactoryBean.getObject());
        factoryBean.setStartDelay(1000);
        factoryBean.setRepeatInterval(5000);
        return factoryBean;
    }

    /**
     * 任务调度
     *
     * @param cronTriggerFactoryBean
     * @param simpleTriggerFactoryBean
     * @return
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, SimpleTriggerFactoryBean simpleTriggerFactoryBean) {
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        factoryBean.setTriggers(cronTriggerFactoryBean.getObject(), simpleTriggerFactoryBean.getObject());
        return factoryBean;
    }
}

如果是配置多个任务,就配置多个JobDetailTrigger即可。