Java 在 Spring 中使用 Quartz
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/562652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Quartz with Spring
提问by a-sak
In my application there is a requirement to be able to create Scheduled Job(s) depending on the type of Request that comes in (Dynamically).
在我的应用程序中,需要能够根据传入的请求类型(动态)创建计划作业。
Can I still use Spring to create and trigger Jobs? If Yes, how?
我还可以使用 Spring 来创建和触发作业吗?如果是,如何?
Any help would be useful.
任何帮助都会有用。
回答by Joe Liversedge
Look at CronTriggerBeanand JobDetailBean. The 'MyJob' class mocked up below is an instance of QuartzJobBean. The cron expression is what you'd expect, but with seconds as its first value.
看看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>
回答by oxbow_lakes
You can also get Spring to trigger methods on your beans using Quartz (i.e. youdon't need to create any Quartz-specific classes at all) using the MethodInvokingJobDetailFactoryBean
in the package org.springframework.scheduling.quartz
您也可以通过让Spring对使用Quartz您的豆触发方法(即youdon't需要在所有创建任何特定的石英类)MethodInvokingJobDetailFactoryBean
在包org.springframework.scheduling.quartz
回答by skaffman
Given that the SchedulerFactoryBean exposes a native Quartz Scheduler object, you can wire that directly into your controller class, and then dynamically create and register triggers and jobs with the Scheduler object.
鉴于 SchedulerFactoryBean 公开了一个原生的 Quartz Scheduler 对象,您可以将它直接连接到您的控制器类中,然后使用 Scheduler 对象动态创建和注册触发器和作业。
Spring itself can't be used for the scheduling of the dynamically created jobs, since Spring's bean support will be used for statically configured jobs, but the native Quartz Scheduler API is reasonable enough to use on its own (barely). As fr triggering of the jobs, that Quartz's job, not Spring's.
Spring 本身不能用于调度动态创建的作业,因为 Spring 的 bean 支持将用于静态配置的作业,但是原生 Quartz Scheduler API 足够合理,可以单独使用(勉强)。作为工作的 fr 触发,Quartz 的工作,而不是 Spring 的工作。
edit: either I'm mis-understanding the original question, or everyone else is. The other answers all detail how to statically wire up a series of quartz jobs using Spring, but the question was how to dynamicallyschedule jobs as requests come in.
编辑:要么我误解了最初的问题,要么其他人都误解了。其他答案都详细说明了如何使用 Spring 静态连接一系列石英作业,但问题是如何在请求进入时动态调度作业。
回答by firstthumb
You can download sample source code from this link
您可以从此链接下载示例源代码
<?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>
回答by Matt
A year later and I find myself having to something very similar. Googling around, I found this linkwhich describes getting access to the application context from within a scheduled job through the JobExecutionContext. I think I will be creating an abstract type job that can do some of the actual job creation and use a prototype to actual inject required services when the job needs to run.
一年后,我发现自己不得不做一些非常相似的事情。谷歌搜索,我找到了这个链接,它描述了通过 JobExecutionContext 从计划的作业中访问应用程序上下文。我想我将创建一个抽象类型的作业,它可以完成一些实际的作业创建,并在作业需要运行时使用原型来实际注入所需的服务。
回答by Rori Stumpf
There does not seem to be much complete information on this. This is how I schedule jobs dynamically. Of course you could replace the simple trigger with some other trigger.
这方面似乎没有太多完整的信息。这就是我动态调度作业的方式。当然,您可以用其他触发器替换简单触发器。
Spring beans:
春豆:
<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>
To run the job immediately get a reference to the scheduler and the job, attach a simple trigger and put it into the scheduler, like this:
要立即运行作业获取对调度程序和作业的引用,请附加一个简单的触发器并将其放入调度程序中,如下所示:
@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);
}
回答by Gerbrand
Spring 3 (latest version at time of writing) supports setting up jobs almost completely with annotations.
Spring 3(撰写本文时的最新版本)支持几乎完全使用注释设置作业。
See: Spring reference on scheduling
请参阅:有关调度的 Spring 参考