❶ spring boot 集成quartz-job如何自動注入spring容器託管之後怎麼動態開啟定時器停
我們通過實現JobFactory 介面,在實例化Job以後,在通過ApplicationContext 將Job所需要的屬性注入即可
在Spring與Quartz集成時 用到的是org.springframework.scheling.quartz.SchelerFactoryBean這個類。源碼如下,我們只看最關鍵的地方。
// Get Scheler instance from SchelerFactory. try {
this.scheler = createScheler(schelerFactory, this.schelerName);
populateSchelerContext();
if (!this.jobFactorySet && !(this.scheler instanceof RemoteScheler)) {
// Use AdaptableJobFactory as default for a local Scheler, unless when // explicitly given a null value through the "jobFactory" bean property. this.jobFactory = new AdaptableJobFactory(); }
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchelerContextAware) {
((SchelerContextAware) this.jobFactory).setSchelerContext(this.scheler.getContext());
}
this.scheler.setJobFactory(this.jobFactory);
}
}
❷ spring 定時器的方法參數是否能動態修改
很多時候,spring的quartz定時任務並不能完全滿足項目的需要,經常會遇到需要任務的執行時間和頻率是可控的,而不是寫死在 quartz配置xml上面。為此,思考了很多動態修改任務執行的方法,以下方法是通過獲取scheler,對trigger的時間表達式進行修改,並重啟任務去實現任務的動態變化。
[java] view plain
public class QuartzHandler {
public static final String DEFAULT_GROUP_NAME = "DEFAULT";
private static QuartzHandler instance = new QuartzHandler();
private static Logger logger = Logger.getLogger(QuartzHandler.class);
private QuartzManager quartzManager;
private Scheler scheler;
private ApplicationContext context;
private QuartzHandler() {
}
public static QuartzHandler genInstance() {
return instance;
}
/**
* 開始定時任務
*/
public void start() {
context = new (
"spring/applicationContext.xml");
scheler = (StdScheler) context.getBean("schelerFactory");
quartzManager = (QuartzManager) context.getBean("quartzManager");
}
/**
* 更新定時任務的觸發表達式
*
* @param triggerName
* 觸發器名字
* @param groupName
* 觸發器組名字
* @param cronExpression
* 觸發表達式
* @return 成功則返回true,否則返回false
*/
public boolean updateCronExpression(String triggerName, String groupName,
String cronExpression) {
try {
CronTrigger trigger = (CronTrigger) getTrigger(triggerName,
groupName);
if (trigger == null) {
return false;
}
if (StringUtils.equals(trigger.getCronExpression(), cronExpression)) {
logger.info("cronExpression is same with the running Schele , no need to update.");
return true;
}
trigger.setCronExpression(cronExpression);
scheler.rescheleJob(trigger.getName(), trigger.getGroup(),
trigger);
logger.info("Update the cronExpression successfully!!");
return true;
} catch (ParseException e) {
logger.error("The new cronExpression - " + cronExpression
+ " not conform to the standard. " + e);
return false;
} catch (SchelerException e) {
logger.error("Fail to reschele. " + e);
return false;
}
}
/**
* 獲取觸發器
*
* @param triggerName
* 觸發器名字
* @param groupName
* 觸發器組名字
* @return 對應Trigger
*/
public Trigger getTrigger(String triggerName, String groupName) {
Trigger trigger = null;
if (StringUtils.isBlank(groupName)) {
logger.warn("Schele Job Group is empty!");
return null;
}
if (StringUtils.isBlank(triggerName)) {
logger.warn("Schele trigger Name is empty!");
return null;
}
try {
trigger = scheler.getTrigger(triggerName, groupName);
} catch (SchelerException e) {
logger.warn("Fail to get the trigger (triggerName: " + triggerName
+ ", groupName : " + groupName + ")");
return null;
}
if (trigger == null) {
logger.warn("Can not found the trigger of triggerName: "
+ triggerName + ", groupName : " + groupName);
}
return trigger;
}
}
❸ spring定時器如何配置
有兩種流行Spring定時器配置:Java的Timer類和OpenSymphony的Quartz。
1.Java Timer定時
首先繼承java.util.TimerTask類實現run方法
import java.util.TimerTask;
public class EmailReportTask extends TimerTask{
@Override
public void run() {
...
}
}
在Spring定義
...
配置Spring定時器
<bean id="scheleReportTask" class="org.springframework.scheling.timer.ScheledTimerTask">
<property name="timerTask" ref="reportTimerTask" />
<property name="period">
<value>86400000value>
property>
bean>
timerTask屬性告訴ScheledTimerTask運行哪個。86400000代表24個小時
啟動Spring定時器
Spring的TimerFactoryBean負責啟動定時任務
<bean class="org.springframework.scheling.timer.TimerFactoryBean">
<property name="scheledTimerTasks">
<list><ref bean="scheleReportTask"/>list>
property>
bean>
scheledTimerTasks里顯示一個需要啟動的定時器任務的列表。
可以通過設置delay屬性延遲啟動
<bean id="scheleReportTask" class="org.springframework.scheling.timer.ScheledTimerTask">
<property name="timerTask" ref="reportTimerTask" />
<property name="period">
<value>86400000value>
property>
<property name="delay">
<value>3600000value>
property>
bean>
這個任務我們只能規定每隔24小時運行一次,無法精確到某時啟動
2.Quartz定時器
首先繼承QuartzJobBean類實現executeInternal方法
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheling.quartz.QuartzJobBean;
public class EmailReportJob extends QuartzJobBean{
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
...
}
}
在Spring中定義
<bean id="reportJob" class="org.springframework.scheling.quartz.JobDetailBean">
<property name="jobClass">
<value>EmailReportJobvalue>
property>
<property name="jobDataAsMap">
<map>
<entry key="courseService">
<ref bean="courseService"/>
entry>
map>
property>
bean>
在這里我們並沒有直接聲明一個EmailReportJob Bean,而是聲明了一個JobDetailBean。這個是Quartz的特點。JobDetailBean是Quartz的org.quartz.JobDetail的子類,它要求通過jobClass屬性來設置一個Job對象。
使用Quartz的JobDetail中的另一個特別之處是EmailReportJob的courseService屬性是間接設置的。JobDetail的jobDataAsMap屬性接受一個Map,包括設置給jobClass的各種屬性,當。JobDetailBean實例化時,它會將courseService Bean注入到EmailReportJob 的courseService 屬性中。
啟動定時器
Quartz的org.quartz.Trigger類描述了何時及以怎樣的頻度運行一個Quartz工作。Spring提供了兩個觸發器SimpleTriggerBean和CronTriggerBean。
SimpleTriggerBean與scheledTimerTasks類似。指定工作的執行頻度,模仿scheledTimerTasks配置 .
<bean id="simpleReportTrigger" class="org.springframework.scheling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="reprotJob" />
<property name="startDelay">
<value>360000value>
property>
<property name="repeatInterval">
<value>86400000value>
property>
bean>
startDelay也是延遲1個小時啟動
CronTriggerBean指定工作的准確運行時間
<bean id="cronReportTrigger" class="org.springframework.scheling.quartz.CronTriggerBean">
<property name="jobDetail" ref="reprotJob" />
<property name="cronExpression">
<value>0 0 6 * * ?value>
property>
bean>
屬性cronExpression告訴何時觸發。最神秘就是cron表達式:
Linux系統的計劃任務通常有cron來承擔。一個cron表達式有至少6個(也可能7個)有空格分隔的時間元素。從左到右:
1.秒2.分3.小時4.月份中的日期(1-31)5.月份(1-12或JAN-DEC)6.星期中的日期(1-7或SUN-SAT)7.年份(1970-2099)
每個元素都顯示的規定一個值(如6),一個區間(9-12),一個列表(9,11,13)或一個通配符(*)。因為4和6這兩個元素是互斥的,因此應該通過設置一個問號(?)來表明不想設置的那個欄位,「/」如果值組合就表示重復次數(10/6表示每10秒重復6次)。
啟動定時器
<bean class="org.springframework.scheling.quartz.SchelerFactoryBean">
<property name="triggers">
<list><ref bean="cronReportTrigger"/>list>
property>
bean>
triggers屬性接受一組觸發器。