2013-08-23 19 views
43

私は、@Scheduledアノテーションを使用して、Springでcronスタイルのpattenrsを持つスケジュールされたジョブを定義しています。Springでスケジュールされたジョブを条件付きで有効または無効にする方法は?

cronパターンは、設定プロパティファイルに格納されます。実際には、1つのデフォルト設定と、環境に依存する1つのプロファイル設定(例えば、dev、test、prod customer 1、prod customer 2など)の2つのプロパティファイルがあり、デフォルト値のいくつかが上書きされます。

私は、私のプロパティーファイルから値をインポートするために、${}スタイルプレースホルダーを使用できる私の春のコンテキストでプロパティープレースホルダーBeanを構成しました。

ジョブBeanは、次のようになります。私のコンテキストXMLの

@Component 
public class ImagesPurgeJob implements Job { 

    private Logger logger = Logger.getLogger(this.getClass()); 

    @Override 
    @Transactional(readOnly=true) 
    @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}") 
    public void execute() { 
     //Do something 
      //can use DAO or other autowired beans here 
    } 
} 

関連部品:私は本当にこのような

<!-- Enable configuration of scheduled tasks via annotations --> 
    <task:annotation-driven/> 

<!-- Load configuration files and allow '${}' style placeholders --> 
    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
     <property name="locations"> 
      <list> 
       <value>classpath:config/default-config.properties</value> 
       <value>classpath:config/environment-config.properties</value> 
      </list> 
     </property> 
     <property name="ignoreUnresolvablePlaceholders" value="true"/> 
     <property name="ignoreResourceNotFound" value="false"/> 
    </bean> 

。最小限のXMLで非常にシンプルできれいです。

しかし、もう1つの要件があります。これらのジョブの一部は、場合によっては完全に無効にすることができます。だから、

、私はそれらを管理するために春を使用する前に、私はそれらを手動で作成し、設定ファイル内のcronパラメータと一緒にブール・パラメータがあり、ジョブを有効にする必要がありかどうかを指定するには:

jobs.mediafiles.imagesPurgeJob.enable=true or false 
jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ? 

この設定パラメータに応じて、このパラメータをSpringで条件付きで作成するか、まったく無視するにはどうすればよいですか?

明白な回避策は、決して評価されないcronパターンを定義することです。そのため、ジョブは決して実行されません。しかし、Beanはまだ作成されており、設定は少し不明なので、よりよい解決策が必要であると感じています。

+0

あなたは今まで、このための答えを見つけましたか? – Chaos

+1

@Chaos:いいえ、まだこれに余分なブール値プロパティを使用しています。 –

+0

"これは決して評価されないcronパターン"が動作しない場合、スプリングスケジューラコードは有効な "次の実行日"を必要とします。それ以外の場合は例外がスローされます。 (すべてのバージョンで真実ではないかもしれません) –

答えて

24
@Component 
public class ImagesPurgeJob implements Job { 

    private Logger logger = Logger.getLogger(this.getClass()); 

    @Value("${jobs.mediafiles.imagesPurgeJob.enable}") 
    private boolean imagesPurgeJobEnable; 

    @Override 
    @Transactional(readOnly=true) 
    @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}") 
    public void execute() { 

     //Do something 
     //can use DAO or other autowired beans here 
     if(imagesPurgeJobEnable){ 

      Do your conditional job here... 

     } 
    } 
} 
+8

これはオプションですが、Beanを作成するよりもBeanをインスタンス化するのではなく、メソッドが何もしなくても定期的に実行されるようにしたいと思います。 –

+0

完璧ではないがシンプルだったので、私はこれをこのように実装した。そして良い@Valueアノテーションについて学びました。 –

+0

聞き取り易い。ありがとうございました... – Prabhakaran

2

あなたの質問は、実際のBeanの作成を条件づけると述べています。少なくともSpring 3.1を使用している場合、このパラメータを使用すると簡単に@Profileを使用できます。 http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html

+0

プロファイルは単純なdev/prod環境のセットでは問題ありませんが、(複数の異なる機能をオン/オフに切り替えている複数の顧客のように)実際に複数のプロダクション環境に適応していないと感じています。ビルド時にアクティブなプロファイルを選択します。現在、すべての環境依存パラメータは1つのプロパティファイルに集中しています。 Springの設定はすべて同じです。私たちが春のプロファイルを使用している場合、それは当てはまりません。 –

+0

カスタムイニシャライザで条件付きでスプリングプロファイルを有効にすることができます(たとえば、ApplicationContextInitializer を拡張してweb.xmlに追加するなど)。次に、イニシャライザで、プロパティを設定して環境を取得し、プロファイルをアクティブにすることができます。 String flag = environment.getProperty( "my.custom.property"); if( "true" .equals(flag)){environment.activateProfile( "MY_CUSTOM_PROFILE")}。私たちは、さまざまな顧客環境のさまざまな機能に対してこれを多く使用しています。また、テスト用の特定の機能を有効/無効にすることもできます(ゼロデプレッションサービスを有効にするなど)。 – jugglingcats

16

春ブーツ@ConditionalOnPropertyを提供し、あなたは春のブートを使用していた場合は完璧になる:

はこちらのドキュメントを参照してください。この注釈は、Spring 4.0.0で導入された @Conditionalの特殊化です。

Spring Bootではなく、通常のSpringを使用していると仮定すると、Spring Bootの@ConditionalOnPropertyを模倣する@ Conditionで使用する独自のCondition実装を作成できます。

+0

理想的にはこれはうまくいくはずですが、Spring Bootの1.3.2-RELEASEの私の場合はそうではありません。 – dARKpRINCE

+0

SpringBoot 1.4.0の@ConditionalOnPropertyでこれを行うことができませんでした。 – ETL

+0

'@ Conditional'ドキュメントによれば、注釈は' @ Bean'で注釈が付けられたメソッドのメソッドレベルでのみ適用されます。 Beanの定義 – jordanpg

14

あなたは、サービスの数に条件により、グループスケジュールの方法をすることができますし、このようにそれらを初期化:

@Service 
@ConditionalOnProperty("yourConditionPropery") 
public class SchedulingService { 

@Scheduled 
public void task1() {...} 

@Scheduled 
public void task2() {...} 

} 
0
@Component 
public class CurrencySyncServiceImpl implements CurrencySyncService { 

    private static Boolean isEnableSync; 
    /** 
    * Currency Sync FixedDelay in minutes 
    */ 
    private static Integer fixedDelay; 

    @Transactional 
    @Override 
    @Scheduled(fixedDelayString = "#{${currency.sync.fixedDelay}*60*1000}") 
    public void sync() { 
     if(CurrencySyncServiceImpl.isEnableSync) { 
      //Do something 
      //you can use DAO or other autowired beans here. 
     } 
    } 

    @Value("${currency.sync.fixedDelay}") 
    public void setFixedDelay(Integer fixedDelay) { 
     CurrencySyncServiceImpl.fixedDelay = fixedDelay; 
    } 

    @Value("${currency.sync.isEnable}") 
    public void setIsEnableSync(Boolean isEnableSync) { 
     CurrencySyncServiceImpl.isEnableSync = isEnableSync; 
    } 
} 
関連する問題