以前說到過Quartz的基本使用(猛戳這裏看文章),在實際使用中,咱們一般會將定時任務交由spring容器來管理,因此今天咱們來講說Quartz與spring的整合。java
我們仍是按照Quartz的三大元素的順序來聊聊整合使用。程序員
在spring中對於Quartz的做業任務管理主要提供了兩種方式,JobDetailFactoryBean和MethodInvokingJobDetailFactoryBean,它們都在org.springframework.scheduling.quartz這個包下。下面咱們來看看它們的使用。spring
spring對這個類的解釋爲:A Spring FactoryBean for creating a Quartz JobDetail instance, supporting bean-style usage for JobDetail configuration.
一個用於建立Quartz JobDetail實例的,支持以bean定義風格來配置JobDetail的工廠bean。併發
對於在spring中的使用也是很簡單,首先咱們須要建立一個具體的做業任務的實現類。使用JobDetailFactoryBean來管理做業任務時,咱們的做業任務實現類須要繼承QuartzJobBean類,並覆蓋其executeInternal方法。就像下面這樣。app
public class SimpleJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException { System.out.println("如今時間爲:"+new Date()); //能夠經過上下文獲取到JobDataMap,這裏面能夠存放一些參數類型的數據 JobDataMap dataMap=arg0.getMergedJobDataMap(); String wish=(String) dataMap.get("wish"); System.out.println(wish); } }
而後就在spring容器中以下配置:ide
<bean id="jobDetailFactoryBeanExample" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- 參考源碼,咱們能夠看到屬性jobClass爲Class類型,因此不能使用ref來引用一個bean,不然就會由於不能將bean轉換爲Class類型而出現異常。 <property name="jobClass" ref="simpleJob"/> 必須使用value對jobClass賦值。 <property name="jobClass" value="com.earl.quartz.spring.job.SimpleJob"/> --> <property name="jobClass" value="com.earl.quartz.spring.job.SimpleJob"/> <!-- 這裏設置的jobDataAsMap能夠傳遞一些參數給做業任務 --> <property name="jobDataAsMap"> <map> <entry key="wish" value="hello"/> </map> </property> </bean>
spring對這個類的解釋:FactoryBean that exposes a JobDetail object which delegates job execution to a specified (static or non-static) method.
這個FactoryBean提供JobDetail對象,這個對象能夠指定做業任務的執行方法。spa
由於能夠指定做業調度時執行的內容,因此使用起來就比JobDetailFactoryBean更加的靈活方便。首先咱們仍是建立一個做業任務的具體實現類,這個實現類就不須要繼承或實現其餘的父類,只須要將咱們想要執行的做業任務聲明在具體的方法中便可。以下:.net
public class ExampleJob{ public void execute(){ System.out.println("如今是"+new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒").format(new Date())); } }
而後在spring容器中以下配置便可:code
<!-- 若是兩個觸發器觸發同一個做業,那麼第二個做業可能在第一個做業完成以前被觸發。 將做業類實現StatefulJob接口就能夠避免這種狀況。 將concurrent設置爲false能夠避免併發的發生。 --> <!-- 使用MethodInvokingJobDetailFactoryBean來建立做業對象 --> <bean id="exampleJob" class="com.earl.quartz.spring.job.ExampleJob"/> <bean id="methodInvokingJobDetailFactoryBeanExample" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!-- 目標對象,指的是做業任務的實現類 --> <property name="targetObject" ref="exampleJob"/> <!-- 目標方法,指的是指定實現類中的哪一個方法做爲調度時的執行方法 --> <property name="targetMethod" value="execute"/> <!-- 是否併發 --> <property name="concurrent" value="false"/> </bean>
以上就是做業任務的相關內容,下面咱們來看看觸發器這個可愛的小東東。orm
在spring中,觸發器也分爲simpleTrigger和cronTrigger,並且它們的使用也是很是簡單,只須要配置一個bean元素便可。下面咱們分別看看它們二者的配置:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <!-- 這裏的JobDetail指的就是咱們配置的做業任務的bean --> <property name="jobDetail" ref="methodInvokingJobDetailFactoryBeanExample" /> <!-- 延遲5秒開始 --> <property name="startDelay" value="5000"></property> <!-- 每3秒重複一次 --> <property name="repeatInterval" value="3000"></property> </bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!-- 這裏的JobDetail指的就是咱們配置的做業任務的bean --> <property name="jobDetail" ref="jobDetailFactoryBeanExample"/> <!--cronExpression,cron表達式--> <property name="cronExpression" value="40 52 17 * * ?"/> </bean>
以上就是觸發器的基本配置,上述兩個觸發器的工廠bean還有一些其餘的屬性,例如jobDataMap,priority等等。若是有須要,您能夠參考相關的文檔。
最後,最簡單的莫過於做業調度程序了,在spring中只須要這樣配置便可:
<bean id="startQuartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false"> <!--指定使用哪些觸發器,spring會去調度觸發相應的觸發器,進而對做業任務進行調度處理--> <property name="triggers"> <list> <!-- <ref bean="simpleTrigger"/> --> <ref bean="cronTrigger"/> </list> </property> </bean>
以上就是對Quartz與Spring的整合使用的基本介紹了。整體來講,Quartz的定時任務功能已經很強大了,而spring對其的整合更是讓程序員在使用定時任務是如虎添翼。對於Quartz來講還有不少其餘的功能,例如定時文件掃描,定時發送郵件等等,以後在另一篇文章中再進行詳細介紹。
猛戳這裏下載源代碼
說明:本文介紹的是Quartz與Spring的整合使用,因此請參考源碼時關注com.earl.quartz.spring包下內容便可,其餘可自行忽略。
在xml配置文件中 加入applicationContextSchedulerContextKey配置
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <!-- <ref bean="simpleTrigger" />--> <ref bean="cronTrigger" /> </list> </property> <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/> </bean>
value的值 用於Job中獲取application上下文對象。 即設置 APPLICATION_CONTEXT_KEY 的值
public class ScheduledJob extends QuartzJobBean { private static final String APPLICATION_CONTEXT_KEY = "applicationContextKey"; private AnotherBean anotherBean; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { ApplicationContext applicationContext = null; try{ applicationContext = getApplicationContext(context); }catch (Exception e){ e.printStackTrace(); } if(applicationContext != null){ System.out.println("applicationContext"); ((AnotherBean)(applicationContext.getBean("anotherBean"))).printAnotherMessage(); } } private ApplicationContext getApplicationContext(JobExecutionContext context) throws Exception { ApplicationContext appCtx = null; appCtx = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY); if (appCtx == null) { throw new JobExecutionException("No application context available in scheduler context for key \"" + APPLICATION_CONTEXT_KEY + "\""); } return appCtx; } }