2

Quartz2のドキュメントによると

RequestsRecovery-ジョブが「リカバリを要求」し、スケジューラの「ハードシャットダウン」時に実行されている場合(つまり、クラッシュ内で実行されているプロセス、またはマシンがシャットダウンされている場合)、ジョブは再実行されます。スケジューラーが再開されたとき。この場合、JobExecutionContext.isRecovering()メソッドはtrueを返します。

Spring3は、Quartz1.xとQuartz2.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>

内部的にorg.springframework.scheduling.quartz.JobDetailBean拡張org.quartz.JobDetailされ、Quartz1.xorg.quartz.JobDetailにはセッターがあり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>

また、Quartz 2.xにはそのようなorg.quartz.JobDetailクラスはありません。代わりに、それはでありinterface、最終的にorg.springframework.scheduling.quartz.JobDetailFactoryBeanはパラメーターを取り<property name="requestsRecovery" value="true" />ません。

parameterこれをQuartzのスケジューラーに渡すにはどうすればよいでしょうか。

4

2 に答える 2

5

クラスのソースコードとQuartz2.0のソースコードを調べたところ、次のようなものがあるorg.springframework.scheduling.quartz.JobDetailFactoryBeanことがわかりました。このメソッド内で、のインスタンスが作成されています。幸い、このインスタンスには、クラスのメソッドを介してアクセスできます。init methodorg.springframework.scheduling.quartz.JobDetailFactoryBeanpublic void afterPropertiesSet()org.quartz.JobDetailorg.quartz.JobDetailpublic 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;
    }
}

そして、春の豆の構成を次のように変更しました。

<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>

そして出来上がり。スケジューラーがタスクを実行している間にサーバーの実行を停止し、サーバーを再起動すると、スケジューラーが未完了のジョブの実行を開始することで、これをテストしました。

それが誰かを助けることを願っています。

于 2012-12-31T12:41:14.017 に答える
1

@tapas-クォーツ情報を検索しているときにあなたの投稿に出くわしました。Spring3.2がプロパティrequestsRecoveryの設定をサポートしているようです。Spring3のバージョンがわかりません。あなたはあなたが問題に直面したあなたの答えの中で言及しました。

セッターインジェクションを介してrequestsRecoveryプロパティを直接設定しましたが、うまくいきました。

  <bean name="continousMonitoringProfileNotificationPushProcessing"     class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
  <property name="jobClass" value="com.mycompany.projectApp.jobs.ContinousMonitoringNotificationPushJobBean" />
    <property name="jobDataAsMap">
        <map>
            <entry key="executionSuccessful" value="true"/>
        </map>
    </property>
    <property name="durability" value="true" /> 
    <property name="requestsRecovery" value="true"/>
 </bean>

JobDetailFactoryBeanのコードを逆コンパイルすると、JObDetailImplインスタンスを作成してrequestsRecoveryを設定するafterPropertiesSetメソッドがオーバーライドされます(以下のように逆コンパイルされたコードの一部)

 public class JobDetailFactoryBean implements FactoryBean<JobDetail>, BeanNameAware, ApplicationContextAware, InitializingBean
 {
 private String name;
 private String group;
 private Class jobClass;
 private JobDataMap jobDataMap = new JobDataMap();
 private boolean durability = false;
 private boolean requestsRecovery = false;

...

.. 

..


 public void afterPropertiesSet()
{
  if (this.name == null) {
  this.name = this.beanName;
 }
  if (this.group == null) {
  this.group = "DEFAULT";
 }
if (this.applicationContextJobDataKey != null) {
 if (this.applicationContext == null) {
        throw new IllegalStateException("JobDetailBean needs to be set up in ApplicationContext to be able to handle an 'applicationContextJobDataKey'");
    }
 getJobDataMap().put(this.applicationContextJobDataKey, this.applicationContext);
 }
 Class<?> jobDetailClass;
 try
 {
      jobDetailClass = getClass().getClassLoader().loadClass("org.quartz.impl.JobDetailImpl");
  }
  catch (ClassNotFoundException ex) {
      jobDetailClass = JobDetail.class;
  }
  BeanWrapper bw = new BeanWrapperImpl(jobDetailClass);
  MutablePropertyValues pvs = new MutablePropertyValues();
  pvs.add("name", this.name);
  pvs.add("group", this.group);
  pvs.add("jobClass", this.jobClass);
  pvs.add("jobDataMap", this.jobDataMap);
  pvs.add("durability", Boolean.valueOf(this.durability));
  pvs.add("requestsRecovery", Boolean.valueOf(this.requestsRecovery));

したがって、JobFactoryBeanクラスを手動で拡張してrequestsRecoveryプロパティを設定する必要はありません。

于 2014-12-11T17:35:50.547 に答える