Spring定时任务[不定时添加任务]

这里讲叙这进在工作上用的到Spring任务。

在项目中,我们需要定时任务来发送微博。当我添加微博后,选择指定的时间发送微博信息时,我们需要添加一个任务[这里是不定时的添加任务],下面的代码就是实现这个功能。

这里我们需要用到Spring的jar包,如果Spring中不包含quartz.jar包,我们这需要下载,然后引用。

下面为web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SpringTask</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:config/spring/applicationContext.xml,classpath*:config/spring/applicationContext-quartz.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Spring的配置文件[这里主要配置了Spring的注解、任务]:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:jaxws="http://cxf.apache.org/jaxws"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:jdbc="http://www.springframework.org/schema/jdbc"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
     http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <!-- enable autowire -->
	<context:annotation-config />

 	<!--自动扫描base-package下面的所有的java类,看看是否配置了annotation -->
    <context:component-scan base-package="com.jing.spring" />

    <!-- enable transaction demarcation with annotations -->
    <tx:annotation-driven />

    <!-- 定时任务的配置 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
        <property name="triggers">
            <list>
            </list>
        </property>
    </bean>
</beans>

java文件:

Task.java[达到任务调用时执行的类]:

package com.jing.spring.scheduler.task;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

/**
 * 定时任务类
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
@Component
public class Task extends TaskAbs {

	// log4j日志
	private static final Logger logger = Logger.getLogger(Task.class);

	/**
	 * 调用定时任务
	 * @param taskId
	 * @param taskType
	 */
	@Override
	public void startTask(String taskId, String taskType) {
		// TODO Auto-generated method stub
		try {
			logger.info("执行TaskJob任务...");
			logger.info("任务编号: " + taskId + "\t任务类型: " + taskType);
			logger.info("在这里加入您需要操作的内容...");
		} catch (Exception e) {
			logger.info("发送微博的定时任务类--出错");
			logger.info(e,e);
		}
	}
}

TaskAbs.java[任务调用的抽象类]:

package com.jing.spring.scheduler.task;

/**
 * 定时任务抽象类
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
public abstract class TaskAbs {

	/** 任务前缀 */
	public final static String TASK_FIRST = "cron_";

	/** 任务ID */
	public final static String TASK_ID = "taskId";

	/** 任务类型 */
	public final static String TASK_TYPE = "taskType";

	/** 任务 */
	public static final String TASK = "task";

	/** 默认的任务过期时间[单位为毫秒] */
	public static final long DEFAULT_PAST_TIME = 0;

	/**
	 * 调用定时任务
	 * @param taskId
	 * @param taskType
	 */
	public abstract void startTask(String taskId, String taskType);

}

TaskJob.java[达到任务调用时的入口]:

package com.jing.spring.scheduler.task;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * 定时任务Job
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
public class TaskJob extends QuartzJobBean {

	//任务类
	private Task task;

	/**
	 * 达到调用定时任务时, 系统会自动调用该方法
	 */
	@Override
	protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
		// TODO Auto-generated method stub
		String taskId = (String) jobExecutionContext.getJobDetail().getJobDataMap().get(TaskAbs.TASK_ID);
		String taskType = (String) jobExecutionContext.getJobDetail().getJobDataMap().get(TaskAbs.TASK_TYPE);
		task.startTask(taskId, taskType);
	}

	public Task getTask() {
		return task;
	}

	public void setTask(Task task) {
		this.task = task;
	}

}

TaskManager.java[添加和删除任务的类]:

package com.jing.spring.scheduler.task;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jing.spring.scheduler.utils.CronExpConversion;

/**
 * 定时任务加载工具类
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
@Component
public class TaskManager {

	private static final Logger logger = Logger.getLogger(TaskManager.class);

	@Autowired
	private Scheduler scheduler;
	@Autowired
	private Task task;

	/**
	 * 添加任务
	 * @param date 定时日期 格式:"YYYY-MM-DD" 例:"2012-06-29"
	 * @param hour 定时小时 格式:"HH" 例:"12"
	 * @param minute 定时分钟 格式:"mm" 例:"59"
	 * @param second 定时秒 格式:"ss" 例:""
	 * @param taskId 微博活动ID[为负数代表我的微博的任务]
	 * @param taskType 活动类型[0:代表我的微博/1:代表活动微博]
	 * @return  false:失败 true:成功
	 */
	public boolean addTask(String date, String hour, String minute, String second, String taskId, String taskType){
		// TODO Auto-generated method stub
		if(date == null || hour == null || minute == null || second == null || taskId == null){
			return false;
		}

		boolean type = false;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

			Date taskDate = sdf.parse(date + " " + hour + ":" + minute + ":" + second);
			Date newDate = Calendar.getInstance().getTime();

			//任务过期加上默认延迟的时间, 则立刻执行
			if(taskDate.getTime() <= (newDate.getTime() + TaskAbs.DEFAULT_PAST_TIME) ) {
				task.startTask(taskId, taskType);
			} else {

			    logger.info("加入任务编号: " + taskId + "\t加入任务类型: " + taskType);

			    //得到调度的任务的String类型的格式[如: 0 0 12 29 6 ?]
			    String cron = CronExpConversion.convertDateToCronExp("userDefined", new String[]{second, minute, hour}, null, null, date);

			    //设置JobDetail的信息
			    JobDetail jobDetail =new JobDetail();
			    jobDetail.setName("job_" + taskType + taskId);
			    jobDetail.getJobDataMap().put(TaskAbs.TASK, task);
			    jobDetail.getJobDataMap().put(TaskAbs.TASK_ID, taskId);
			    jobDetail.getJobDataMap().put(TaskAbs.TASK_TYPE, taskType);
			    jobDetail.setJobClass(TaskJob.class);
			scheduler.addJob(jobDetail, true);

			//创建任务
			CronTrigger cronTrigger = new CronTrigger(TaskAbs.TASK_FIRST + taskType + taskId, Scheduler.DEFAULT_GROUP, jobDetail.getName(), Scheduler.DEFAULT_GROUP);
			cronTrigger.setCronExpression(cron);

			//设置任务
			scheduler.scheduleJob(cronTrigger);
			}type = true;
		} catch (ParseException e) {
			logger.info("添加任务--错误!");
			logger.info(e,e);
		} catch (SchedulerException e) {
			logger.info("添加任务--错误!");
			logger.info(e,e);
		}

		return type;
	}

	/**
	 * 删除任务
	 * @param taskId 微博活动ID
	 * @param taskType 活动类型[0:代表我的微博/1:代表活动微博]
	 * @return  false:失败 true:成功
	 */
	public boolean cancelTask(Long taskId, String taskType){
		// TODO Auto-generated method stub
		if(taskId == null){
			return false;
		}
		logger.info("取消任务编号: " + taskId + "\t取消任务类型: " + taskType);
		boolean type = false;
		try {
			scheduler.unscheduleJob(TaskAbs.TASK_FIRST + taskType + taskId, Scheduler.DEFAULT_GROUP);
			type = true;
		} catch (SchedulerException e) {
			logger.info("删除任务--错误!");
			logger.info(e,e);
		}
		return type;
	}

}

CronExpConversion.java:

package com.jing.spring.scheduler.utils;

/**
 * 时间任务处理类
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
public class CronExpConversion {

	/**
	 * 页面设置转为UNIX cron expressions 转换算法
	 *  @param  everyWhat
	 *  @param  commonNeeds 包括 second minute hour
	 *  @param  monthlyNeeds 包括 第几个星期 星期几
	 *  @param  weeklyNeeds  包括 星期几
	 *  @param  userDefinedNeeds  包括具体时间点
	 *  @return   cron expression
	 */
	public static String convertDateToCronExp(String everyWhat, String[] commonNeeds, String[] monthlyNeeds, String weeklyNeeds, String userDefinedNeeds)  {
		// TODO Auto-generated method stub
		String cronEx = "" ;
		String commons = commonNeeds[ 0 ] + " " + commonNeeds[ 1 ] + " " + commonNeeds[ 2 ] +  " " ;
		String dayOfWeek = "";
		if  ("monthly".equals(everyWhat))  {
			//  eg.: 6#3 (day 6 = Friday and "#3" = the 3rd one in the
			//  month)
			dayOfWeek  =  monthlyNeeds[ 1 ]
			                            +  CronExRelated.specialCharacters
			                            .get(CronExRelated._THENTH)  +  monthlyNeeds[ 0 ];
			cronEx  =  (commons
					+  CronExRelated.specialCharacters.get(CronExRelated._ANY)
					+   "   "
					+  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
					+   "   "   +  dayOfWeek  +   "   " ).trim();
		}   else   if  ( "weekly" .equals(everyWhat))  {
			dayOfWeek  =  weeklyNeeds;  //  1
			cronEx  =  (commons
					+  CronExRelated.specialCharacters.get(CronExRelated._ANY)
					+   "   "
					+  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
					+   "   "   +  dayOfWeek  +   "   " ).trim();
		}   else   if  ( "userDefined" .equals(everyWhat))  {
			String dayOfMonth  =  userDefinedNeeds.split( "-" )[ 2 ];
			if  (dayOfMonth.startsWith( "0" ))  {
				dayOfMonth  =  dayOfMonth.replaceFirst( "0" ,  "" );
			}
			String month  =  userDefinedNeeds.split( "-" )[ 1 ];
			if  (month.startsWith( "0" ))  {
				month  =  month.replaceFirst( "0" , "" );
			}
			// FIXME 暂时不加年份 Quartz报错
			//	           String year  =  userDefinedNeeds.split( " - " )[ 0 ];
			/* cronEx = (commons + dayOfMonth + " " + month + " "
	                   + CronExRelated.specialCharacters.get(CronExRelated._ANY)
	                   + " " + year).trim(); */
			cronEx  =  (commons  +  dayOfMonth  +   " "   +  month  +   " "
					+  CronExRelated.specialCharacters.get(CronExRelated._ANY)
					+   " " ).trim();
		}
		return  cronEx;
	}


	public static void main(String[] args) {
		String cron = CronExpConversion.convertDateToCronExp("userDefined", new String[]{"0","0","12"}, null, null, "2012-06-29");
		System.out.println(cron);
	}
}

CronExRelated.java:

package com.jing.spring.scheduler.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * Quartz时间规则常量类
 * @author  jing.yue
 * @version 2012/07/24 1.0.0
 */
public class CronExRelated {

	public static final String _EVERY = "every";
	public static final String _ANY = "any";
	public static final String _RANGES = "ranges";
	public static final String _INCREMENTS = "increments";
	public static final String _ADDITIONAL = "additional";
	public static final String _LAST = "last";
	public static final String _WEEKDAY = "weekday";
	public static final String _THENTH = "theNth";
	public static final String _CALENDAR = "calendar";

	public static final String _TYPE = "type";

	/**
	 * 0 0 6 ? * 1#1 ? monthly
	 * 0 0 6 ? * 1 ? weekly
	 * 0 0 6 30 7 ? 2006 useDefined
	 */
	static String[] headTitle = {"TYPE","SECONDS","MINUTES","HOURS","DAYOFMONTH","MONTH","DAYOFWEEK","YEAR"};

	/**
	 * cron expression special characters
	 * Map
	 * specialCharacters
	 */
	public static Map<String,Object> specialCharacters;

	static {
		specialCharacters = new HashMap<String,Object>(10);
		specialCharacters.put(_EVERY, "*");
		specialCharacters.put(_ANY, "?");
		specialCharacters.put(_RANGES, "-");
		specialCharacters.put(_INCREMENTS, "/");
		specialCharacters.put(_ADDITIONAL, ",");
		specialCharacters.put(_LAST, "L");
		specialCharacters.put(_WEEKDAY, "W");
		specialCharacters.put(_THENTH, "#");
		specialCharacters.put(_CALENDAR, "C");

		specialCharacters.put(_TYPE, headTitle);
	}

	public static void set(String ex, int index) {
		// TODO Auto-generated method stub
		((String[])specialCharacters.get(_TYPE))[index] = ex;
	}
}

下面附上添加任务的jsp:

<%@page  import="java.text.SimpleDateFormat"%>
<%@page  import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page  import="org.springframework.web.context.WebApplicationContext"%>
<%@page  import="com.jing.spring.scheduler.task.TaskManager"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W4C//DTD HTML 4.01 Transitional//EN" "http://www.w4.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
打开index.jsp自动添加10个任务
<%
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
TaskManager taskManager = (TaskManager) wac.getBean("taskManager");
taskManager.addTask("2012-07-24", "15", "40", "00", "0", "test");
taskManager.addTask("2012-07-24", "15", "41", "00", "1", "test");
taskManager.addTask("2012-07-24", "15", "42", "00", "2", "test");
taskManager.addTask("2012-07-24", "15", "43", "00", "3", "test");
taskManager.addTask("2012-07-24", "15", "44", "00", "4", "test");
taskManager.addTask("2012-07-24", "15", "45", "00", "5", "test");
taskManager.addTask("2012-07-24", "15", "46", "00", "6", "test");
taskManager.addTask("2012-07-24", "15", "47", "00", "7", "test");
taskManager.addTask("2012-07-24", "15", "48", "00", "8", "test");
taskManager.addTask("2012-07-24", "15", "49", "00", "9", "test");
%>
</body>
</html>

这就是Spring任务了。

你可能感兴趣的:(QuartzJobBean,spring定时任务)