6

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

我仍然可以使用 Spring 来创建和触发 Jobs 吗?如果是,如何?

任何帮助都会很有用。

4

7 回答 7

12

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

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

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

于 2009-03-01T22:40:38.120 回答
4

查看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>
于 2009-02-18T20:35:01.287 回答
4

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

春豆:

<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);
    }   
于 2012-04-27T14:30:45.557 回答
3

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

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

于 2009-07-28T13:11:02.107 回答
2

您也可以使用MethodInvokingJobDetailFactoryBean包中的org.springframework.scheduling.quartz

于 2009-02-18T21:21:25.607 回答
1

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

请参阅:关于调度的 Spring 参考

于 2012-08-16T09:51:19.377 回答
1

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

于 2010-02-15T13:57:56.287 回答