文档章节

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

岳静
 岳静
发布于 2012/07/24 15:59
字数 1916
阅读 904
收藏 22

这里讲叙这进在工作上用的到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任务了。

© 著作权归作者所有

岳静

岳静

粉丝 45
博文 19
码字总数 8678
作品 0
深圳
高级程序员
私信 提问
加载中

评论(11)

筱龙缘
筱龙缘
求jar包
岳静
岳静 博主

引用来自“web智能”的评论

引用来自“蟋蟀MM”的评论

引用来自“web智能”的评论

TaskManager 中的67行, JobDetail我这怎么是一个接口,无法new, 是不是我这版本的问题,我下的最新的2.1.6

我的版本是1.8.4的

哦,了解,我去下一个,谢谢啦!

不客气
删除
删除

引用来自“蟋蟀MM”的评论

引用来自“web智能”的评论

TaskManager 中的67行, JobDetail我这怎么是一个接口,无法new, 是不是我这版本的问题,我下的最新的2.1.6

我的版本是1.8.4的

哦,了解,我去下一个,谢谢啦!
岳静
岳静 博主

引用来自“web智能”的评论

TaskManager 中的67行, JobDetail我这怎么是一个接口,无法new, 是不是我这版本的问题,我下的最新的2.1.6

我的版本是1.8.4的
岳静
岳静 博主

引用来自“web智能”的评论

TaskManager 中的67行, JobDetail我这怎么是一个接口,无法new, 是不是我这版本的问题,我下的最新的2.1.6

额,高级的版本是没有jobDetail了
删除
删除
TaskManager 中的67行, JobDetail我这怎么是一个接口,无法new, 是不是我这版本的问题,我下的最新的2.1.6
岳静
岳静 博主

引用来自“web智能”的评论

引用来自“Jimmy_牛牛”的评论

引用来自“涟漪叶”的评论

这么长,懒的看……

需要它的人会看完的。。

不错,正在看

删除
删除

引用来自“Jimmy_牛牛”的评论

引用来自“涟漪叶”的评论

这么长,懒的看……

需要它的人会看完的。。

不错,正在看
打酱油君
打酱油君
呵呵
岳静
岳静 博主

引用来自“涟漪叶”的评论

这么长,懒的看……

需要它的人会看完的。。
Spring Boot实践--定时任务两种(Schedule与Quartz整合)

Spring Boot实践--定时任务两种(Schedule与Quartz整合) 最近在项目中使用到定时任务,之前一直都是使用Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实...

spinachgit
2018/02/11
392
0
spring boot实现动态增删启停定时任务

在spring boot项目中,可以通过@EnableScheduling注解和@Scheduled注解实现定时任务,也可以通过SchedulingConfigurer接口来实现定时任务。但是这两种方式不能动态添加、删除、启动、停止任务...

jessehua
04/22
0
0
崛起于Springboot2.0.X之集成Quartz定时调度(29)

下面是两种方法定时任务,一个是集成quartz,另外一个是spring自带的定时任务,后者更简单一些。 该博客为入门级博客,如果想要查看企业使用Quartz场景,点击 --> 手动操作定时任务 1、pom依...

木九天
2018/07/24
4K
0
分布式定时任务框架---Uncode Schedule

分布式定时任务框架---Uncode Schedule rabbitGYK 关注 2016.11.27 20:36* 字数 1446 阅读 7141评论 5喜欢 36赞赏 1 博客原文 作为一个支付公司的项目组,经常会有很多对账功能(签约对账、支...

晨猫
2018/11/02
149
0
在Spring项目中使用@Scheduled注解定义简单定时任务

如题所示,有时候我们需要在Web项目中配置简单的定时任务,而且因为任务并不复杂不想使用定时调度框架(PS:Quartz、ActiveMQ 、Kafka等),这时就可以考虑使用@Scheduled注解来定义简单的定...

pangfc
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
今天
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
今天
6
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部