Spring整合Quartz实现定时任务步骤很简单,大致需要经过如下几步:创建任务(Job)、配置JobDetail、配置触发器(Trigger)、配置SchedulerFactoryBean。
一、准备开发环境
1、首先使用Maven创建一个web项目并引入quartz的依赖
<!--quartz-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<!--quartz-->
2、需要创建Spring配置文件,并在web.xml文件中引入Spring支持
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
二、实现定时任务
1、创建任务(Job)
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.collections.MapUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import com.sohu.tv.vrs.service.BaseService;
import com.sohu.tv.vrs.service.annotion.TimerName;
import com.sohu.tv.vrs.service.enums.DataTypeEnum;
import com.sohu.tv.vrs.service.ms.DataOperateStatService;
@TimerName("统计push_temp表中类别缺省的数量")
public class PushTmpCategoryIsNullCnt extends BaseService implements Job{
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ApplicationContext wcx = getContext(context);
DataOperateStatService service = (DataOperateStatService)wcx.getBean(DataOperateStatService.class);
long s = System.currentTimeMillis();
Map<String, Object> cnt=service.getPushTmpCategoryIsNullCnt();
Long total=(Long) cnt.get("total");
Long firstCount=(Long) cnt.get("firstCount");
Long secondCount=(Long) cnt.get("secondCount");
Long topicCount=(Long) cnt.get("topicCount");
Calendar cal=Calendar.getInstance();
cal.add(Calendar.DATE, -1);
Date yesterday =cal.getTime();
String dateTime=DateUtil.formatDate(yesterday, "yyyy-MM-dd 00:00:00");
Integer affected_rows=service.insertCategoryCount(DataTypeEnum.catogery_cnt.getValue(), total, firstCount, secondCount, topicCount, dateTime);
long e = System.currentTimeMillis();
logger.info("compute category count end,store into ms success,affected row:{} spend:{} mills",affected_rows,(e-s));
}
}
2、在Spring配置文件中配置JobDetail和触发器
<!-- 计算PushTmp表中类别的缺省数量 by jiangxingqi -->
<bean id="computePushTempCatogeryIsNullCntDetail"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass">
<value>com.sohu.tv.vrs.timer.push.PushTmpCategoryIsNullCnt</value>
</property>
<property name="name" value="computePushTempCatogeryIsNullCntDetail"></property>
<property name="durability" value="true" />
</bean>
<bean id="computePushTempCatogeryIsNullCntTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="computePushTempCatogeryIsNullCntDetail" />
<!-- 每天凌晨2点运行一次 -->
<property name="cronExpression" value="0 * 2 * * ?" />
</bean>
3、配置SchedulerFactoryBean
<context:component-scan base-package="com.sohu.tv.vrs.quartz"/>
<task:executor id="quartzTaskExecutor" keep-alive="900" pool-size="10" queue-capacity="20" />
<!-- Quartz集群Schduler -->
<bean id="clusterQuartzScheduler-online" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- Triggers集成 -->
<property name="triggers">
<list>
<!--统计PushTemp表中类别为空的数量 -->
<ref bean="computePushTempCatogeryIsNullCntTrigger"/>
</list>
</property>
<!-- quartz配置文件路径, 指向cluster配置 -->
<property name="configLocation" value="classpath:quartz-cluster.properties" />
<!-- 启动时延期2秒开始任务 -->
<property name="startupDelay" value="2" />
<!-- 保存Job数据到数据库所需的数据源 -->
<property name="dataSource" ref="dataSourcePushback" />
<!-- Job接受applicationContext的成员变量名 -->
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<!-- 修改job时,更新到数据库 -->
<property name="overwriteExistingJobs" value="true" />
</bean>