Использование кварца с пружиной - PullRequest
6 голосов
/ 18 февраля 2009

В моем приложении есть требование создавать запланированные задания в зависимости от типа поступающего запроса (динамически).

Могу ли я по-прежнему использовать Spring для создания и запуска заданий? Если да, то как?

Любая помощь будет полезна.

Ответы [ 7 ]

12 голосов
/ 02 марта 2009

Учитывая, что SchedulerFactoryBean предоставляет собственный объект Quartz Scheduler, вы можете подключить его непосредственно к классу контроллера, а затем динамически создавать и регистрировать триггеры и задания с помощью объекта Scheduler.

Сам Spring не может быть использован для планирования динамически создаваемых заданий, поскольку поддержка bean-компонентов Spring будет использоваться для статически настраиваемых заданий, но собственный API Quartz Scheduler достаточно разумен, чтобы использовать его сам по себе (едва ли). Как запуск рабочих мест, это работа Кварца, а не весны.

edit: либо я неправильно понимаю исходный вопрос, либо все остальные. В другом ответе подробно рассказывается, как статически подключить серию кварцевых заданий с помощью Spring, но вопрос заключался в том, как динамически планировать задания по мере поступления запросов.

4 голосов
/ 27 апреля 2012

По-видимому, нет полной информации по этому вопросу. Вот как я планирую работу динамически. Конечно, вы можете заменить простой триггер другим.

Весенние бобы:

<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);
    }   
4 голосов
/ 18 февраля 2009

Посмотрите на 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>
3 голосов
/ 28 июля 2009

Образец исходного кода можно загрузить с по этой ссылке

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

2 голосов
/ 19 февраля 2009

Вы также можете заставить Spring вызывать методы ваших компонентов с помощью Quartz (т.е. вам вообще не нужно создавать какие-либо классы, специфичные для Quartz), используя MethodInvokingJobDetailFactoryBean в пакете org.springframework.scheduling.quartz

1 голос
/ 16 августа 2012

Spring 3 (последняя версия на момент написания) поддерживает настройку заданий практически полностью с аннотациями.

См .: Ссылка на пружину при планировании

1 голос
/ 15 февраля 2010

Год спустя, и я обнаружил, что мне нужно что-то очень похожее. Погуглив, я нашел эту ссылку , которая описывает получение доступа к контексту приложения из запланированного задания через JobExecutionContext. Я думаю, что буду создавать задание абстрактного типа, которое может выполнять некоторые фактические задачи по созданию рабочих мест и использовать прототип для фактического внедрения необходимых служб, когда задание должно быть запущено.

...