最近在 開發中 要使用定時器進行 做服務器定時任務 廢話不多說:
框架 ssm+dubbo
quartzjar 包
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
quartz 的使用有兩種方式: 一種是 java 代碼實現 , 另一種是在 spring 的 xml 中進行配置 這裏我們只對 xml 配置這種方式進行講解說明:
因爲使用了 dubbo 所以在 facade 層中進行配置相關配置
首先配置
這裏的定時器任務是爲了定時的請求網易雲服務器獲取上傳到網易雲服務器的視頻的播放地址, 因爲網易雲視頻上傳非 MP4 格式的視頻會有個轉碼時間, 爲了解決本地庫中一些視頻地址字段值的缺失 所以使用改定時器進行每間隔一個週期去請求網易雲
1. 編寫要執行的類和方法
public class VideoUrlService {
private static final Logger logger = LoggerFactory.getLogger(ConsumerUserFacadeImpl.class);
// private Scheduler scheduler;
@Resource
private VideoService videoService;
public VideoService getVideoService() {
return videoService;
}
public void setVideoService(VideoService videoService) {
this.videoService = videoService;
}
public void getAllVideoUrl() throws Exception {
try {
List<VideoDTO> list = videoService.getAllVideoList();
if (list != null && list.size() != 0) {
for (VideoDTO v : list) {
String vid = v.getVid();
String sdMp4Url = VideoUtils.getSdMp4Url(vid);
if (sdMp4Url != null) {
v.setVideoUrl(sdMp4Url);
}
}
Integer flag = videoService.updateVidelList4List(list);
if (flag > 0) {
logger.info("批量獲取雲視頻地址成功");
System.out.println("獲取視頻地址成功");
} else {
logger.info("批量獲取雲視頻地址失敗");
System.out.println("獲取視頻地址失敗");
}
}
} catch (Exception e) {
logger.error("執行網易雲任務出錯了...");
JobExecutionException jobe = new JobExecutionException(e);
jobe.setRefireImmediately(true);
throw jobe;
}
}
需要注意的是: 當任務執行發生錯誤的時候怎麼辦?
quartz 提供了兩種方案: 1 立即重新執行任務 (這種只會停止當前任務執行)2. 立即停止所有相關這個任務的觸發器 (該任務的觸發器被停止後不會進行再被觸發)
那麼怎麼解決呢?
1 立即重新執行任務:
(注意看代碼註釋)
try {
int zero = 0;
@SuppressWarnings("unused")
int calculation = 4815 / zero;
} catch (Exception e) {
_log.error("執行任務出錯了...");
JobExecutionException jobe =
new JobExecutionException(e);
// this job will refire immediately
jobe.setRefireImmediately(true);
throw jobe;
}
2 立即終止該任務執行
(注意看代碼註釋)
try {
int zero = 0;
@SuppressWarnings("unused")
int calculation = 4815 / zero;
} catch (Exception e) {
_log.info("--- Error in job!");
JobExecutionException jobe =
new JobExecutionException(e);
// Quartz will automatically unschedule
// all triggers associated with this job
// so that it does not run again
jobe.setUnscheduleAllTriggers(true);
throw jobe;
}
2. 在 spring 的配置文件中進行配置
// 配置要執行的任務類
<bean id="videoUrlService" class="com.spacexplore.VideoUrlService">
<property name="videoService" ref="videoService"></property>
</bean>
//定義觸發任務
<bean id="videoUrlJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="videoUrlService"/>
</property>
<property name="targetMethod" value="getAllVideoUrl"/> <!-- 要執行的方法名稱 -->
</bean>
// 定義調度觸發器
<bean id="videoUrlTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="videoUrlJob"></property>
<property name="cronExpression">
<value>0 0/5 * * * ?</value>//這裏做測試我們設置爲每5分鐘進行請求網易雲
</property>
</bean>
// 定義調度工廠類
<bean id="schedulerFactory"class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" autowire="no">
<property name="triggers">
<list>
<!--在這裏可以定義多個觸發器-->
<ref bean="ldCodeTrigger" />
<ref bean="videoUrlTrigger"/>
</list>
</property>
</bean>
** 值得一提的是:
1.lazy-init 如果設置爲 true,這任務工程在服務器啓動時不會加載。所以這裏必須設置爲 false。
2. 由於在上邊的配置中定義的了 default-autowire=”byName”, Spring 會自動注入 quartz 中的 datasource bean,所以會報異常。 解決方法:在 bean 中關掉 autowired**