工作中常常遇到需要定時執行任務的需求,記錄一下
**1.引入相關需要的jar包**
**2.配置檔案**
**3.編寫任務業務邏輯**
第二步:配置檔案
Spring建立jobDetailbean 有兩種方式分别是
配置Spring的任務排程抽象層簡化了任務排程,在Quartz的基礎上提供了更好的排程對象。Spring使用Quartz架構來完成任務排程,建立Quartz的作業Bean(JobDetail),有以下兩種方法:
1:利用JobDetailBean包裝QuartzJobBean子類(即Job類)的執行個體。 2:利用MethodInvokingJobDetailFactoryBean工廠Bean包裝普通的Java對象(即Job類)。
說明:
1:采用第一種方法 建立job類,一定要繼承QuartzJobBean ,實作 executeInternal(JobExecutionContext jobexecutioncontext)方法,此方法就是被排程任務的執行體,然後将此Job類的執行個體直接配置到JobDetailBean中即可。這種方法和在普通的Quartz程式設計中是一樣的。
2:采用第二種方法 建立Job類,無須繼承父類,直接配置MethodInvokingJobDetailFactoryBean即可。但需要指定一下兩個屬性:
targetObject:指定包含任務執行體的Bean執行個體。
targetMethod:指定将指定Bean執行個體的該方法包裝成任務的執行體。 concurrent:是否并發進行,false,表示不可以并發,其他程序延遲調用,一般用于定時調用多個程式時。
第一種實作
<bean name="autoCardAmortizeJob" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="default" autowire="default">
<property name="jobClass" value="cn.xx.job.AutoOrderAmortizeJob" />
<property name="jobDataAsMap">
<map><entry key="size" value="10" /></map>
</property>
<property name="applicationContextJobDataKey" value="applicationContext" />
</bean>
**● jobClass:類型為Class,實作Job接口的任務類;
● beanName:預設為Bean的id名,通過該屬性顯式指定Bean名稱,對應任務的名稱;
● jobDataAsMap:類型為Map,為任務所對應的JobDataMap提供值。之是以需要提供這個屬性,是因為除非你手工注冊一 個編輯器,你不能直接配置JobDataMap類型的值,是以Spring通過jobDataAsMap設定JobDataMap的值;
●applicationContextJobDataKey:你可以将Spring ApplicationContext的引用儲存到JobDataMap中,以便在Job的代碼中通路ApplicationContext。為了達到這個目的,你需要指定一個鍵,用以在jobDataAsMap中儲存ApplicationContext,如果不設定此鍵,JobDetailBean就不将ApplicationContext放入到JobDataMap中;
●jobListenerNames:類型為String[],指定注冊在Scheduler中的JobListeners名稱,以便讓這些監聽器對本任務的事件進行監聽**。
第二種實作
<bean name="autoCardAmortizeJob" class="cn.xx.job.AutoOrderAmortizeJob"/>
<bean id="autoCardAmortizeJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="autoCardAmortizeJob" />
<property name="targetMethod" value="studyCardAmortize" />
<property name="concurrent" value="false" />
</bean>
**說明:1. targetObject:指定包含任務執行體的Bean執行個體。
2. targetMethod:指定将指定Bean執行個體的該方法包裝成任務的執行體。
3.concurrent:是否并發進行,false,表示不可以并發,其他程序延遲調用,一般用于定時調用多個程式時。**
觸發器配置
<!--學習卡自動攤銷任務觸發器配置 -->
<bean id="autoCardAmortizeCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="autoCardAmortizeJobDetail" />
<!-- 每5秒鐘執行一次 -->
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
排程配置
<!-- 總配置 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 添加觸發器 -->
<property name="triggers">
<list>
<ref bean="autoCardAmortizeCronTrigger" />
</list>
</property>
</bean>
最後就可以在自己的job中寫自己的業務邏輯
/***
* 訂單自動攤銷任務
*
*
*/
public class AutoOrderAmortizeJob{
private Logger log;
@Autowired
private TeacherAchievementNewService teacherAchievementNewService;
public void studyCardAmortize() throws Exception {
try {
System.out.println("目前時間是"+DateUtil.format(new Date(), DateUtil.BOTH));
List<TeacherInfo> teacherInfoList = teacherAchievementNewService.getTeacherInfo();
for (TeacherInfo teacherInfo : teacherInfoList) {
System.out.println(teacherInfo.getTeacherName());
}
} catch (Exception e) {
log.error("自動學習卡攤銷任務執行異常!");
e.printStackTrace();
}
}
完整配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 總配置 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 添加觸發器 -->
<property name="triggers">
<list>
<ref bean="autoCardAmortizeCronTrigger" />
</list>
</property>
</bean>
<!--學習卡自動攤銷任務配置 -->
<bean name="autoCardAmortizeJob" class="cn.xxx.scheduler.job.AutoOrderAmortizeJob"/>
<bean id="autoCardAmortizeJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="autoCardAmortizeJob" />
<property name="targetMethod" value="studyCardAmortize" />
<property name="concurrent" value="false" />
</bean>
<!--學習卡自動攤銷任務觸發器配置 -->
<bean id="autoCardAmortizeCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="autoCardAmortizeJobDetail" />
<!-- 每5秒鐘執行一次 -->
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
</beans>
還有種更為簡單的實作方式那就是 —–注解
如下:
package com.main.scheduler.job;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TimeSayHelloJobAnnoation {
// 每5秒執行一次
@Scheduled(cron = "0 0/2 * * * ? ")
public void myTest() {
System.out.println("注解方式定時器進入測試"+new Date().toString());
}
}
使用注解方式隻需記得在spring配置檔案中啟用注解即可
<!-- 啟動Spring MVC的注解功能,完成請求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
遇到的問題:
Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
原因是Spring 3.0版本中内置的Quartz版本是<2.0的,在使用最新的Quartz包(>2.0)之後,接口不相容。
解決辦法有兩種:
1.降低Quartz版本,降到1.X去。
2.更新Spring版本到3.1+,根據Spring的建議,将原來的**TriggerBean替換成**TriggerFactoryBean,例如CronTriggerBean 就可以替換成 CronTriggerFactoryBean。替換之後問題解決。
2014-04-22補充解決辦法:
解決辦法有三種:
1.降低Quartz版本,降到1.X去。
2.更新Spring版本到3.1+,根據Spring的建議,将原來的**TriggerBean替換成**TriggerFactoryBean,例如CronTriggerBean 就可以替換成 CronTriggerFactoryBean。替換之後問題解決。
3.如果不在xml配置檔案中引用 Spring 3.0 是支援 Quartz2.2.1(目前最新版本),直接在程式中調用即可。(我們的檔案中轉站系統用的是 Spring 3.0+quartz 2.2.1叢集模式)
原文位址:http://www.cnblogs.com/interdrp/p/3587221.html
http://blog.csdn.net/zeb_perfect/article/details/50826079