使用 Quartz 和 Spring

发布于 2024-07-14 00:46:23 字数 106 浏览 8 评论 0原文

在我的应用程序中,需要能够根据传入的请求类型(动态)创建计划作业。

我还可以使用 Spring 创建和触发作业吗? 如果是,怎么办?

任何帮助都会有用的。

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?

Any help would be useful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

哎呦我呸! 2024-07-21 00:46:24

鉴于 SchedulerFactoryBean 公开了本机 Quartz Scheduler 对象,您可以将其直接连接到控制器类中,然后使用 Scheduler 对象动态创建和注册触发器和作业。

Spring 本身不能用于动态创建作业的调度,因为 Spring 的 bean 支持将用于静态配置的作业,但本机 Quartz Scheduler API 足够合理,可以单独使用(勉强)。 至于工作的触发,是 Quartz 的工作,而不是 Spring 的工作。

编辑:要么我误解了原来的问题,要么其他人都是。 其他答案都详细介绍了如何使用 Spring 静态连接一系列石英作业,但问题是如何在收到请求时动态调度作业。

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.

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.

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 dynamically schedule jobs as requests come in.

分开我的手 2024-07-21 00:46:24

看看 CronTriggerBeanJobDetailBean。 下面模拟的“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>

Look at CronTriggerBean and 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.

<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>
薄荷港 2024-07-21 00:46:24

这方面似乎没有太多完整的信息。 这就是我动态安排工作的方式。 当然,您可以用其他触发器替换简单触发器。

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>     

要立即运行作业,请获取对调度程序和作业的引用,附加一个简单的触发器并将其放入调度程序中,如下所示:

    @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);
    }   

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);
    }   
酒废 2024-07-21 00:46:24

您还可以使用org.springframework.scheduling包中的MethodInvokingJobDetailFactoryBean让Spring使用Quartz触发您的bean上的方法(即您根本不需要创建任何特定于Quartz的类) .quartz

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

青衫儰鉨ミ守葔 2024-07-21 00:46:24

您可以从此链接下载示例源代码

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

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>

不弃不离 2024-07-21 00:46:24

一年后,我发现自己不得不做一些非常相似的事情。 谷歌搜索,我发现这个链接 它描述了通过 JobExecutionContext 从计划作业中访问应用程序上下文。 我想我将创建一个抽象类型的作业,它可以完成一些实际的作业创建,并在作业需要运行时使用原型来实际注入所需的服务。

A year later and I find myself having to something very similar. Googling around, I found this link which 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.

好多鱼好多余 2024-07-21 00:46:24

Spring 3(撰写本文时的最新版本)几乎完全支持使用注释来设置作业。

请参阅: Spring 调度参考

Spring 3 (latest version at time of writing) supports setting up jobs almost completely with annotations.

See: Spring reference on scheduling

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文