私のアプリケーションでは、(動的に) 入ってくるリクエストのタイプに応じて、スケジュールされたジョブを作成できる必要があります。
Spring を使用してジョブを作成およびトリガーすることはできますか? はいの場合、どのように?
どんな助けでも役に立ちます。
私のアプリケーションでは、(動的に) 入ってくるリクエストのタイプに応じて、スケジュールされたジョブを作成できる必要があります。
Spring を使用してジョブを作成およびトリガーすることはできますか? はいの場合、どのように?
どんな助けでも役に立ちます。
SchedulerFactoryBean がネイティブの Quartz Scheduler オブジェクトを公開する場合、それをコントローラ クラスに直接接続し、Scheduler オブジェクトを使用してトリガーとジョブを動的に作成および登録できます。
Spring の Bean サポートは静的に構成されたジョブに使用されるため、動的に作成されたジョブのスケジューリングに Spring 自体を使用することはできませんが、ネイティブの Quartz Scheduler API は単独で (かろうじて) 使用するのに十分合理的です。ジョブのトリガーとしては、Spring ではなく Quartz のジョブです。
編集:元の質問を誤解しているか、他のすべての人が誤解しています。他の回答はすべて、Spring を使用して一連のクォーツ ジョブを静的に接続する方法を詳しく説明していますが、問題は、リクエストが入ったときにジョブを動的にスケジュールする方法でした。
これに関する完全な情報はあまりないようです。これは、ジョブを動的にスケジュールする方法です。もちろん、単純なトリガーを他のトリガーに置き換えることもできます。
春豆:
<bean name="dailyUpdateJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.somecompany.scheduler.DailyUpdates" />
</bean>
<bean id="dailyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="dailyUpdateJob" />
<!-- run every morning at 4:15 AM -->
<property name="cronExpression" value="00 15 04 * * ?" />
</bean>
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="dailyCronTrigger" />
<ref bean="weeklyReportsCronTrigger" />
</list>
</property>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>
ジョブをすぐに実行するには、スケジューラとジョブへの参照を取得し、次のように単純なトリガーをアタッチしてスケジューラに配置します。
@Autowired
SchedulerFactoryBean scheduler;
@Autowired
@Qualifier("dailyUpdateJob")
JobDetailFactoryBean dailyJob;
public void dynamicJobTrigger() throws Exception {
// Create a trigger for "now"
SimpleTrigger trigger = (SimpleTrigger) newTrigger()
.startAt(new Date())
.forJob(dailyJob.getObject())
.build();
// And drop it into the scheduler for immediate execution
scheduler.getScheduler().scheduleJob(trigger);
}
CronTriggerBeanとJobDetailBeanを見てください。以下にモックアップされている「MyJob」クラスは、QuartzJobBeanのインスタンスです。cron 式は期待どおりですが、最初の値は秒です。
<beans>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="startupDelay" value="5"/>
<property name="waitForJobsToCompleteOnShutdown" value="false"/>
<property name="triggers">
<list>
<bean class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="edu.vt.MyJob"/>
<property name="jobDataAsMap">
<map>
<entry key="messageSource" value-ref="messageSource"/>
<entry>
<key><value>anotherProperty</value></key>
<bean class="edu.vt.MyUsefulBean">
<constructor-arg index="0" value="..."/>
</bean>
</entry>
</map>
</property>
</bean>
</property>
<property name="cronExpression" value="0 * * * * ?"/>
</bean>
</list>
</property>
</bean>
</beans>
このリンクからサンプル ソース コードをダウンロードできます。
<?xml version="1.0" encoding="UTF-8"?>
<!-- scheduler factory -->
<bean id="com.notary.app.invoicing.scheduler.SchedulerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="ASFImportTrigger"/>
</list>
</property>
<property name="dataSource">
<ref bean="datasource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.MSSQLDelegate</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?</prop>
<prop key="org.quartz.plugin.triggHistory.class">org.quartz.plugins.history.LoggingTriggerHistoryPlugin</prop>
<prop key="org.quartz.plugin.triggHistory.triggerFiredMessage">Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss dd/MM/yyyy}</prop>
<prop key="org.quartz.plugin.triggHistory.triggerCompleteMessage">Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss dd/MM/yyyy} with resulting trigger instruction code: {9}</prop>
<prop key="org.quartz.plugin.jobHistory.class">org.quartz.plugins.history.LoggingJobHistoryPlugin</prop>
<prop key="org.quartz.plugin.jobHistory.jobSuccessMessage">Job {1}.{0} fired at: {2, date, dd/MM/yyyy HH:mm:ss} result=OK</prop>
<prop key="org.quartz.plugin.jobHistory.jobFailedMessage">Job {1}.{0} fired at: {2, date, dd/MM/yyyy HH:mm:ss} result=ERROR</prop>
</props>
</property>
<property name="overwriteExistingJobs" value="true"/>
<property name="startupDelay" value="50"/>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>
パッケージMethodInvokingJobDetailFactoryBean
内のorg.springframework.scheduling.quartz
1年後、私は自分が非常に似たようなことをしなければならないことに気づきました。ぐぐってみると、JobExecutionContext を介してスケジュールされたジョブ内からアプリケーション コンテキストにアクセスする方法を説明するこのリンクが見つかりました。実際のジョブ作成の一部を実行し、プロトタイプを使用して、ジョブを実行する必要があるときに必要なサービスを実際に注入できる抽象タイプのジョブを作成すると思います。
Spring 3 (執筆時点での最新バージョン) は、アノテーションを使用したジョブのセットアップをほぼ完全にサポートしています。