最近在 开发中 要使用定时器进行 做服务器定时任务 废话不多说:
框架 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**