Quartz использует объекты Trigger
, Job
и JobDetail
для реализации планирования всех видов задач. Об основных понятиях, лежащих в основе Quartz, см. на сайте Quartz. Для обеспечения удобства Spring предусматривает несколько классов, которые упрощают использование Quartz в приложениях на базе Spring.
Использование JobDetailFactoryBean
Объекты JobDetail
из Quartz содержат всю информацию, необходимую для выполнения задачи. Spring предусматривает JobDetailFactoryBean
, который предоставляет свойства в стиле бинов для целей конфигурации XML. Рассмотрим следующий пример:
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="example.ExampleJob"/>
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="5"/>
</map>
</property>
</bean>
Конфигурация детализации задачи содержит всю информацию, необходимую для выполнения задачи (ExampleJob
). Врем ожидания указывается в карте данных задачи. Карта данных задачи доступна через JobExecutionContext
(передается вам во время выполнения), но JobDetail
также получает свои свойства из данных задачи, отображенных на свойства экземпляра задачи. Так, в следующем примере ExampleJob
содержит свойство бина с именем timeout
, а в JobDetail
оно применяется автоматически:
package example;
public class ExampleJob extends QuartzJobBean {
private int timeout;
/**
* Сеттер, вызываемый после создания экземпляра ExampleJob,
* со значением из JobDetailFactoryBean (5)
*/
public void setTimeout(int timeout) {
this.timeout = timeout;
}
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
// выполняем фактическую работу
}
}
Вам также доступны любые дополнительные свойства из карты данных задачи.
name
и group
можно изменить имя и группу задачи соответственно. По умолчанию имя задачи совпадает с именем бина JobDetailFactoryBean(exampleJob
в предыдущем примере выше).Использование MethodInvokingJobDetailFactoryBean
Зачасту требуется просто вызвать метод для определенного объекта. Используя MethodInvokingJobDetailFactoryBean
, можно сделать именно это, как показано в следующем примере:
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject"/>
<property name="targetMethod" value="doIt"/>
</bean>
Предыдущий пример приводит к тому, что метод doIt
вызывается для метода exampleBusinessObject
, как показано в следующем примере:
public class ExampleBusinessObject {
// свойства и взаимодействующие объекты
public void doIt() {
// выполняем фактическую работу
}
}
<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>
При использовании MethodInvokingJobDetailFactoryBean
не требуется создавать однострочные задачи, которые лишь вызывают метод. Требуется лишь создать реальный бизнес-объект и связать с объектом детализации.
По умолчанию задачи в Quartz не имеют статического характера, что приводит к тому, что задачи могут мешать друг другу. Если вы зададите два триггера для одного и того же класса JobDetail
, возможно, что до завершения первой задачи начнется вторая. Если классы JobDetail
реализуют интерфейс Stateful
, то этого не происходит. Вторая задача не начинается до завершения первой. Для того чтобы задачи, получаемые от MethodInvokingJobDetailFactoryBean
, не выполнялись параллельно, установите флаг concurrent
в false
, как показано в следующем примере:
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject"/>
<property name="targetMethod" value="doIt"/>
<property name="concurrent" value="false"/>
</bean>
Связывание задач с помощью триггеров и SchedulerFactoryBean
Мы создали детализацию задачи и задачи. Мы также рассмотрели вспомогательные бины, которые позволяют вызывать метод для определенного объекта. Конечно, нам все еще нужно составить расписание самих задач. Для этого используются триггеры и SchedulerFactoryBean
. В Quartz доступно несколько триггеров, а Spring предусматривает две реализации FactoryBean
для Quartz с удобными настройками по умолчанию: CronTriggerFactoryBean
и SimpleTriggerFactoryBean
.
Триггеры должны быть запланированы. Spring предлагает SchedulerFactoryBean
, который открывает триггеры для настройки в качестве свойств. SchedulerFactoryBean
планирует фактические задания с этими триггерами.
В следующем листинге используются как SimpleTriggerFactoryBean
, так и CronTriggerFactoryBean
:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<!-- see the example of method invoking job above -->
<property name="jobDetail" ref="jobDetail"/>
<!-- 10 секунд -->
<property name="startDelay" value="10000"/>
<!-- повторяем каждые 50 секунд... -->
<property name="repeatInterval" value="50000"/>
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="exampleJob"/>
<!-- выполняем каждое утро в 6 утра... -->
<property name="cronExpression" value="0 0 6 * * ?"/>
</bean>
В предыдущем примере установлены два триггера: один запускается каждые 50 секунд с начальной задержкой в 10 секунд, а другой запускается каждое утро в 6 часов утра. Чтобы завершить все, нам нужно установить SchedulerFactoryBean
, как показано в следующем примере:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
<ref bean="simpleTrigger"/>
</list>
</property>
</bean>
Для SchedulerFactoryBean
доступны дополнительные свойства, такие как календари, используемые детализацией задачи, свойства для настройки Quartz и DataSource из JDBC, передаваемый Spring. Дополнительную информацию см. в javadoc по SchedulerFactoryBean
.
SchedulerFactoryBean
также распознает файл quartz.properties
в classpath, основываясь на ключах свойств Quartz, как и при обычной конфигурации Quartz. Обратите внимание, что многие настройки SchedulerFactoryBean
взаимодействуют с общими настройками Quartz в файле свойств; поэтому не рекомендуется задавать значения на обоих уровнях. Например, не устанавливайте свойство "org.quartz.jobStore.class", если хотите использовать DataSource, предоставляемый Spring, или задайте вариант org.springframework.scheduling.quartz.LocalDataSourceJobStore
, который является полноценной заменой стандартного org.quartz.impl.jdbcjobstore.JobStoreTX
.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ