Spring 3的Quartz 2实现不再支持requestsRecovery

Tap*_*ose 2 java quartz-scheduler spring-3

根据Quartz 2的文档

RequestsRecovery - 如果一个作业"请求恢复",并且它正在调度程序的"硬关闭"期间执行(即它在崩溃中运行的进程,或者机器被关闭),那么它将被重新执行当调度程序再次启动时.在这种情况下,JobExecutionContext.isRecovering()方法将返回true.

Spring3支持Quartz 1.x和Quartz 2.x. 如果我们使用Quartz 1.x那么我们需要使用以下配置来创建JobDetailbean:

<bean id="ldapSynch" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="com.edfx.adb.scheduling.job.LDAPSynchronizer" />
    <property name="requestsRecovery" value="true" />       
</bean>
Run Code Online (Sandbox Code Playgroud)

内部org.springframework.scheduling.quartz.JobDetailBean扩展org.quartz.JobDetail并在Quartz 1.x中org.quartz.JobDetail有一个setter public void setRequestsRecovery(boolean shouldRecover).

但是如果我们使用Spring3的Quartz 2.x实现那么上述配置会改变为:

<bean id="ldapSynch" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="com.edfx.adb.scheduling.job.LDAPSynchronizer" />
    <property name="requestsRecovery" value="true" />       
</bean>
Run Code Online (Sandbox Code Playgroud)

并且在Quartz 2.x中没有这样的org.quartz.JobDetail类,而是它是一个interface并且最终org.springframework.scheduling.quartz.JobDetailFactoryBean不再采用参数<property name="requestsRecovery" value="true" />.

我们怎样才能将这个重要的内容传递parameter给Quartz的调度程序?

Tap*_*ose 5

寻找到类的源代码后org.springframework.scheduling.quartz.JobDetailFactoryBean石英2.0和源代码,我发现,有一种init methodorg.springframework.scheduling.quartz.JobDetailFactoryBeanpublic void afterPropertiesSet(); 在此方法中,org.quartz.JobDetail正在创建实例.幸运的是,这个实例org.quartz.JobDetail可以通过public JobDetail getObject()类的方法访问org.springframework.scheduling.quartz.JobDetailFactoryBean.

在Quartz 2.0中,该类org.quartz.impl.JobDeialImpl实现了接口org.quartz.JobDetail; 所以org.quartz.JobDetailin org.springframework.scheduling.quartz.JobDetailFactoryBean的实例实际上是org.quartz.impl.JobDeialImpl.的实例.

所以我创建了一个com.edfx.adb.scheduling.ADBJobDetailFactoryBean扩展org.springframework.scheduling.quartz.JobDetailFactoryBean和覆盖afterPropertiesSet()方法的类:

package com.edfx.adb.scheduling;

import org.quartz.impl.JobDetailImpl;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;

public class ADBJobDetailFactoryBean extends JobDetailFactoryBean {

    private boolean requestsRecovery;

    public ADBJobDetailFactoryBean() {
        super();
    }

    @Override
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        JobDetailImpl jobDetail = (JobDetailImpl) getObject();
        jobDetail.setRequestsRecovery(isRequestsRecovery());
    }

    public boolean isRequestsRecovery() {
        return requestsRecovery;
    }

    public void setRequestsRecovery(boolean requestsRecovery) {
        this.requestsRecovery = requestsRecovery;
    }
}
Run Code Online (Sandbox Code Playgroud)

并将spring bean配置更改为:

<bean id="ldapSynch" class="com.edfx.adb.scheduling.ADBJobDetailFactoryBean">
    <property name="jobClass" value="com.edfx.adb.scheduling.job.LDAPSynchronizer" />
    <property name="requestsRecovery" value="true" />       
</bean>
Run Code Online (Sandbox Code Playgroud)

瞧.我通过在调度程序执行任务时停止运行服务器来测试这一点,当我重新启动服务器时,调度程序开始执行未完成的作业.

希望它会帮助某人.