Quartz之整合Spring

前言

作为Web开发者, Spring是必不可少的一个框架, 自然需要把Quartz整合进去。所幸网上已有很多教程, 我这里也只是简单的整合一下, 用于以后项目的CV大法。
Quartz 有调度器Scheduler、触发器 Trigger、任务 JobDetail三个组件。一个任务可以给多个调度器执行,触发器在指定时间运行任务,调度器操作触发器执行定时任务。

maven配置

这里的 Spring 版本是 4.3.9.RELEASE , Quartz 版本是 2.3.0

创建任务JobDetail的两种方法

  1. 使用 MethodInvokingJobDetailFactoryBean 通过反射调用 Bean的方法
  2. 使用 JobDetailFactoryBean, 必须搭配 QuartzJobBean

推荐用第一种方法, 低侵入式, 降低耦合性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 第一种创建任务的方法, 不依赖框架的Java Bean形式
public class MyBean1 {
public void hello(String msg){
System.out.println(this.getClass().getSimpleName()+" : "+ DateFormatUtils.format(System.currentTimeMillis(),"yyyy-MM-dd HH:mm:ss")+" : "+msg);
}
}

// 第二种创建任务的方法, 依赖spring-context-support
// org.springframework.scheduling.quartz.QuartzJobBean
public class MyBean2 extends QuartzJobBean {
private String key;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(this.getClass().getSimpleName()+" : "+ DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss"));
}

public void setKey(String key) {
this.key = key;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<beans >
<bean id="myBean1" class="com.ahao.MyBean1"/>

<!-- 反射调用Bean的某个方法, 传入arguments参数 -->
<bean id="myBeanJob1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myBean1"/>
<property name="targetMethod" value="hello"/>
<property name="arguments">
<list>
<value>hello World!</value>
</list>
</property>
</bean>

<!-- 依赖QuartzJobBean -->
<bean id="myBeanJob2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- MyBean2必须继承QuartzJobBean -->
<property name="jobClass" value="com.ahao.MyBean2"/>
<!-- 参数通过setter方法注入 -->
<property name="jobDataAsMap">
<map>
<entry key="key" value="value"/>
</map>
</property>
<!-- 未绑定Trigger时不会抛出异常 -->
<property name="durability" value="true"/>
</bean>
</beans>

创建触发器Trigger的两种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<beans >
<bean id="trigger1" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="myBeanJob1"/>
<!-- 延迟1秒启动 -->
<property name="startDelay" value="1000"/>
<!-- 每2秒触发一次 -->
<property name="repeatInterval" value="2000"/>
</bean>

<bean id="trigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="myBeanJob2"/>
<!-- cron表达式 -->
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
</beans>

创建调度器

1
2
3
4
5
6
7
8
9
10
<beans>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger1"/>
<ref bean="trigger2"/>
</list>
</property>
</bean>
</beans>

运行

启动Tomcat服务器, 看到控制台有输出即可。
完整的 spring-quartz.xml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="myBean1" class="com.ahao.MyBean1"/>

<!-- 反射调用Bean的某个方法, 传入arguments参数 -->
<bean id="myBeanJob1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myBean1"/>
<property name="targetMethod" value="hello"/>
<property name="arguments">
<list>
<value>hello World!</value>
</list>
</property>
</bean>

<!-- 依赖QuartzJobBean -->
<bean id="myBeanJob2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- MyBean2必须继承QuartzJobBean -->
<property name="jobClass" value="com.ahao.MyBean2"/>
<!-- 参数通过setter方法注入 -->
<property name="jobDataAsMap">
<map>
<entry key="key" value="value"/>
</map>
</property>
<!-- 未绑定Trigger时不会抛出异常 -->
<property name="durability" value="true"/>
</bean>

<bean id="trigger1" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="myBeanJob1"/>
<!-- 延迟1秒启动 -->
<property name="startDelay" value="1000"/>
<!-- 每2秒触发一次 -->
<property name="repeatInterval" value="2000"/>
</bean>

<bean id="trigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="myBeanJob2"/>
<!-- cron表达式 -->
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger1"/>
<ref bean="trigger2"/>
</list>
</property>
</bean>
</beans>