下面分开讲解 spring 3.XXX + quartz 1.XXX和 spring4.XXX + quartz2. xxx
一、spring4.XXX + quartz2. xxx
<properties> <spring.version>4.3.0.RELEASE</spring.version> </properties>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency>
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; import java.util.Date; public class QuartzMethodOne extends QuartzJobBean { private static int counter = 0; protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("-----------QuartzMethodOne"); //下面是业务的具体实现 long ms = System.currentTimeMillis(); System.out.println("\t\t" + new Date(ms)); System.out.println(ms); System.out.println("(" + counter++ + ")"); String s = (String) context.getMergedJobDataMap().get("service"); System.out.println(s); System.out.println("-----------QuartzMethodOne"); } }
import java.util.Date; public class QuartzMethodTwo { private static int counter = 0; public void execute() { System.out.println("-----------QuartzMethodTwo"); //下面是业务的具体实现 long ms = System.currentTimeMillis(); System.out.println("\t\t" + new Date(ms)); System.out.println(ms); System.out.println("(" + counter++ + ")"); System.out.println("-----------QuartzMethodTwo"); } }
<!-- 配置调度程序quartz ,其中配置JobDetail有两种方式 --> <!--方式一:使用JobDetailBean,任务类必须实现Job接口 --> <bean id="one" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="name" value="exampleJob"></property> <property name="jobClass" value="com.gxp.quartz.QuartzMethodOne"></property> <!-- 在这个例子中,jobDataAsMap没有用,此目标类中接受的参数 ,若参数为service,则可以在此进行参数配置,类似struts2 --> <property name="jobDataAsMap"> <map> <entry key="service"> <value>simple is the beat</value> </entry> </map> </property> </bean> <!-- 方式二:使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法--> <!-- 定义目标bean和bean中的方法 --> <bean id="quartzMethodTwo" class="com.gxp.quartz.QuartzMethodTwo"/> <bean id="two" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="quartzMethodTwo"/> </property> <property name="targetMethod"> <!-- 要执行的方法名称 --> <value>execute</value> </property> </bean> <!-- =====================方法一:调度触发器 ======================== --> <!-- 定义simpleTrigger触发器 --> <!-- <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="jobDetail"></property> <property name="repeatCount"> <value>8</value> </property> <property name="repeatInterval"> <value>1000</value> </property> <property name="startDelay"> <value>4</value> </property> </bean> --> <!-- 另一种触发器是CornTrigger --> <bean id="oneCornTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="one"/> <!-- 每个10秒触发 --> <property name="cronExpression" value="0/5 * * * * ?"/> </bean> <!-- ======================== 方法二:调度触发器 ======================== --> <bean id="twoCornTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="two"/> <!-- 每个10秒触发 --> <property name="cronExpression" value="0/5 * * * * ?"/> </bean> <!-- ======================== 调度工厂 ======================== --> <bean id="SpringJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="oneCornTrigger"/> <ref bean="twoCornTrigger"/> </list> </property> </bean>
二、spring 3.XXX + quartz 1.XXX
参考文章:http://kevin19900306.iteye.com/blog/1397744#comments,http://blog.youkuaiyun.com/dos_186/article/details/47784549
最近在研究Spring中的定时任务功能,最好的办法当然是使用Quartz来实现。
我使用的是Maven来管理项目,需要的Jar包我给大家贴出来。
quartz-1.8.5.jar
commons-logging.jar
spring-core-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring.transaction-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
Maven的pom.xml的配置:
- <properties>
- <springframework.version>3.0.5.RELEASE</springframework.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>${springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>1.8.5</version>
- </dependency>
- </dependencies>
- <build>
- <finalName>${project.artifactId}</finalName>
- <plugins>
- <plugin>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>7.5.4.v20111024</version>
- <configuration>
- <scanIntervalSeconds>10</scanIntervalSeconds>
- <webApp>
- <contextPath>/${project.artifactId}</contextPath>
- </webApp>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
特别注意一点,与Spring3.1以下版本整合必须使用Quartz1,最初我拿2.1.3的,怎么搞都报错:
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name 'mytrigger' defined in class path resource [applicationContext.xml]: problem with class file or dependent class; nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
查看发现spring3.0.5中org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTrigger(public class CronTriggerBeanextends CronTrigger),而在quartz2.1.3中org.quartz.CronTrigger是个接口(publicabstract interface CronTrigger extends Trigger),而在quartz1.8.5及1.8.4中org.quartz.CronTrigger是个类(publicclass CronTrigger extends Trigger),从而造成无法在applicationContext中配置触发器。这是spring3.1以下版本和quartz2版本不兼容的一个bug。(感谢tiren的回复,spring3.1以及以后版本支持quartz2)
在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通类。很显然,第二种方式远比第一种方式来的灵活。
第一种方式的JAVA代码:
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
public class QuartzMethodOne extends QuartzJobBean {
private static int counter = 0;
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("-----------QuartzMethodOne");
//下面是业务的具体实现
long ms = System.currentTimeMillis();
System.out.println("\t\t" + new Date(ms));
System.out.println(ms);
System.out.println("(" + counter++ + ")");
String s = (String) context.getMergedJobDataMap().get("service");
System.out.println(s);
System.out.println("-----------QuartzMethodOne");
}
}
public class QuartzMethodTwo { private static int counter = 0; public void execute() { System.out.println("-----------QuartzMethodTwo"); //下面是业务的具体实现 long ms = System.currentTimeMillis(); System.out.println("\t\t" + new Date(ms)); System.out.println(ms); System.out.println("(" + counter++ + ")"); System.out.println("-----------QuartzMethodTwo"); } }
Spring的配置文件:
- <!------------ 配置调度程序quartz ,其中配置JobDetail有两种方式-------------->
- <!--方式一:使用JobDetailBean,任务类必须实现Job接口 -->
- <bean id="one" class="org.springframework.scheduling.quartz.JobDetailBean">
- <property name="name" value="exampleJob"></property>
- <property name="jobClass" value="XXXX.QuartzMethodOne"></property>
- <property name="jobDataAsMap">
- <map>
- <entry key="service"><value>simple is the beat</value></entry>
- </map>
- ;/property>
- </bean>
- <!-- 方式二:使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
- <!-- 定义目标bean和bean中的方法 -->
- <bean id="quartzMethodTwo" class="XXXX.QuartzMethodTwo"/>
- <bean id="two" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject">
- <ref bean="quartzMethodTwo"/>
- </property>
- <property name="targetMethod"> <!-- 要执行的方法名称 -->
- <value>execute</value>
- </property>
- </bean>
- <!-- =====================方法一:调度触发器 ======================== -->
- <bean id="oneCronTrigger class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail" ref="one"></property>
- <property name="cronExpression" value="0/5 * * * * ?"></property>
- </bean>
- <!-- ======================== 方法二:调度触发器 ======================== -->
- <bean id="twoCronTrigger class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail" ref="two"></property>
- <property name="cronExpression" value="0/5 * * * * ?"></property>
- </bean>
- <!-- ======================== 调度工厂 ======================== -->
- <bean id="SpringJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref bean="oneCronTrigger"/>
- <ref bean="twoCronTrigger"/>
- </list>
- </property>
- </bean>
最后别忘了在web.xml里面配置Spring:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- </welcome-file-list>
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/spring-config.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- </web-app>