`
ynztpwl
  • 浏览: 55837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring动态定时器封装

 
阅读更多
今天在网上看到一篇文章,对spring定时器进行动态的增,删,改。很有启发,自己动手封装了一下,有些代码是copy那篇文章的,我不知道那篇文章最原始的地址了,无法在此贴出来,先声明一下。


我很少些博文,估计写得不好。


大概意思就是利用spring对quartz的封装实现动态添加定时任务,无需在配置文件中配置定时器。这个在具体系统中还是有比较大的应用面的,这些动态定时器可以来自数据库,来自业务代码。

首先spring的配置还是要得,不过只需要一个bean,配置如下:
<bean id="schedulerFactory"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
</bean>

然后任务封装类,需要进行添加的任务可以new这个类的一个对象设置好属性就好了:
public class CustomJob {
	public static final int JS_ENABLED = 0; // 任务启用状态
	public static final int JS_DISABLED = 1; // 任务禁用状态
	public static final int JS_DELETE = 2; // 任务已删除状态

	private String jobId; // 任务的Id,一般为所定义Bean的ID
	private String jobName; // 任务的描述
	private String jobGroup; // 任务所属组的名称
	private int jobStatus; // 任务的状态,0:启用;1:禁用;2:已删除
	private String cronExpression; // 定时任务运行时间表达式
	private String memos; // 任务描述
	private Class<?> stateFulljobExecuteClass;//同步的执行类,需要从StatefulMethodInvokingJob继承
	private Class<?> jobExecuteClass;//异步的执行类,需要从MethodInvokingJob继承
        /**
	 * 得到该job的Trigger名字
	 * @return
	 */
	public String getTriggerName() {
		return this.getJobId() + "Trigger";
	}
        /*私有字段的get,set省略*/
}

然后任务管理器封装类,这个类是对任务的统一管理功能,有增,删,查,改
/**
 * 
 */
package org.liyaojin.quartz.dynamic;

import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdScheduler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author jl_love
 * 
 *         2011-10-14 豁达,坚强,勤奋
 */
public class QuartzManager {
	private static Scheduler scheduler;

	static {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"quartzDynamic.xml");
		scheduler = (StdScheduler) context.getBean("schedulerFactory");
	}

	/**
	 * 启动一个自定义的job
	 * 
	 * @param schedulingJob
	 *            自定义的job
	 * @param paramsMap
	 *            传递给job执行的数据
	 * @param isStateFull
	 *            是否是一个同步定时任务,true:同步,false:异步
	 * @return 成功则返回true,否则返回false
	 */
	public static boolean enableCronSchedule(CustomJob schedulingJob,
			JobDataMap paramsMap, boolean isStateFull) {
		if (schedulingJob == null) {
			return false;
		}
		try {
			CronTrigger trigger = (CronTrigger) scheduler
					.getTrigger(schedulingJob.getTriggerName(),
							schedulingJob.getJobGroup());
			if (null == trigger) {// 如果不存在该trigger则创建一个
				JobDetail jobDetail = null;
				if (isStateFull) {
					jobDetail = new JobDetail(schedulingJob.getJobId(),
							schedulingJob.getJobGroup(),
							schedulingJob.getStateFulljobExecuteClass());
				} else {
					jobDetail = new JobDetail(schedulingJob.getJobId(),
							schedulingJob.getJobGroup(),
							schedulingJob.getJobExecuteClass());
				}
				jobDetail.setJobDataMap(paramsMap);
				trigger = new CronTrigger(schedulingJob.getTriggerName(),
						schedulingJob.getJobGroup(),
						schedulingJob.getCronExpression());
				scheduler.scheduleJob(jobDetail, trigger);
			} else {
				// Trigger已存在,那么更新相应的定时设置
				trigger.setCronExpression(schedulingJob.getCronExpression());
				scheduler.rescheduleJob(trigger.getName(), trigger.getGroup(),
						trigger);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 禁用一个job
	 * 
	 * @param jobId
	 *            需要被禁用的job的ID
	 * @param jobGroupId
	 *            需要被警用的jobGroupId
	 * @return 成功则返回true,否则返回false
	 */
	public static boolean disableSchedule(String jobId, String jobGroupId) {
		if (jobId.equals("") || jobGroupId.equals("")) {
			return false;
		}
		try {
			Trigger trigger = getJobTrigger(jobId, jobGroupId);
			if (null != trigger) {
				scheduler.deleteJob(jobId, jobGroupId);
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 得到job的详细信息
	 * 
	 * @param jobId
	 *            job的ID
	 * @param jobGroupId
	 *            job的组ID
	 * @return job的详细信息,如果job不存在则返回null
	 */
	public static JobDetail getJobDetail(String jobId, String jobGroupId) {
		if (jobId.equals("") || jobGroupId.equals("") || null == jobId
				|| jobGroupId == null) {
			return null;
		}
		try {
			return scheduler.getJobDetail(jobId, jobGroupId);
		} catch (SchedulerException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 得到job对应的Trigger
	 * 
	 * @param jobId
	 *            job的ID
	 * @param jobGroupId
	 *            job的组ID
	 * @return job的Trigger,如果Trigger不存在则返回null
	 */
	public static Trigger getJobTrigger(String jobId, String jobGroupId) {
		if (jobId.equals("") || jobGroupId.equals("") || null == jobId
				|| jobGroupId == null) {
			return null;
		}
		try {
			return scheduler.getTrigger(jobId + "Trigger", jobGroupId);
		} catch (SchedulerException e) {
			e.printStackTrace();
			return null;
		}
	}

}

最后给出测试代码:
1:任务类
   /**
 * 
 */
package org.liyaojin.quartz.dynamic;

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

/**
 * @author jl_love
 *
 * 2011-10-14
 * 豁达,坚强,勤奋
 */
public class QuartzJobOne extends StatefulMethodInvokingJob {
	private static int i = 0;
	private int j = 0; /*说明每次执行都是new了一个新的执行类,具有线程安全性*/
	/* (non-Javadoc)
	 * @see org.springframework.scheduling.quartz.QuartzJobBean#executeInternal(org.quartz.JobExecutionContext)
	 */
	@Override
	protected void executeInternal(JobExecutionContext context)
			throws JobExecutionException {
		j++;/*说明每次执行都是new了一个新的执行类,具有线程安全性*/
		i++;
		System.out.println("j====>" + j);/*说明每次执行都是new了一个新的执行类,具有线程安全性*/
		System.out.println("这是我得第" + i + "次执行");
		System.out.println("my name is QuartzJobOne");
		System.out.println(context.getJobDetail().getJobDataMap().get("p2"));/*拿到传入的数据*/
		if(i == 3){
			System.out.println("我只执行三次.....");
			QuartzManager.disableSchedule("job1","job1_group");
		}
	}
}


测试main方法:

/**
 * 
 */
package org.liyaojin.quartz.dynamic;

import java.util.ArrayList;

import org.quartz.JobDataMap;

/**
 * @author jl_love
 *
 * 2011-10-14
 * 豁达,坚强,勤奋
 */
public class QuartzManagerTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CustomJob job = new CustomJob();
		job.setJobId("job1");
		job.setJobGroup("job1_group");
		job.setJobName("第一个测试定时器");
		job.setMemos("我是第一个测试定时器的描述");
		job.setCronExpression("0/5 * * * * ?");//每五秒执行一次
		job.setStateFulljobExecuteClass(QuartzJobOne.class);
		
		JobDataMap paramsMap = new JobDataMap();
		ArrayList<String> paramList = new ArrayList<String>();
		paramList.add("one");
		paramList.add("two");
		paramList.add("three");
		
		paramsMap.put("p1","p1");
		paramsMap.put("p2",paramList);
		QuartzManager.enableCronSchedule(job, paramsMap, true);
	}

}


具体原理我就不多说了,重在实用。其实也没什么技术含量,主要就是调用quartz的api同时利用了spring对quartz的封装。只是为了方便自己,也为了方便大家。

我会附上该测试工程的源码,我使用的是spring 3.0.2中dist下所有的jar包,以及spring依赖包中的apacheCommons底下所有的jar包,还有quartz的jar包,我会附上jar包得截图放在源码的压缩包里面。

源代码下载地址:http://dl.iteye.com/topics/download/7a2de849-d08b-32ac-a6cf-844b35ef848f

分享到:
评论

相关推荐

    struts2+spring3+hibernate4 + UI 组件(easyui)+代码生成器+共通封装+Spring_security权限

    数据字典封装, 邮件发送封装,定时器封装,hibernate+spring jdbc组合使用 [4].完整用户权限封装 权限可直接使用 功能:权限,角色,用户 [5].ehcache缓存机制(永久缓存/临时缓存) 代码生成器界面: A.动态选择...

    Spring从入门到精通 源码

     全书共分14章,内容涵盖了Spring的基础概念、核心容器、Spring AOP、事务处理、持久层封装、Web框架、定时器、Spring和Struts、Spring和Hibernate、Spring和Ant、Spring和Junit。本书适用于...

    Spring从入门到精通(珍藏版)

     全书共分14章,内容涵盖了Spring的基础概念、核心容器、Spring AOP、事务处理、持久层封装、Web框架、定时器、Spring和Struts、S pring和Hibernate、Spring和Ant、Spring和Junit。本书适用于初、中级软件开发人员...

    springCloud.rar(私聊博主要密码)

    + springBoot + springCloud + 日志组件logback-spring + 多配置 + 多数据源...+ 传参注解式校验 + session练习 + 公用日志设计封装 + db乐观锁设计 + 优雅启停 + 配置文件信息加密 + AES加解密 + spring 事件监听设计

    基于SpringBoot2.0的具备支付功能的已上线大型OA项目

    系统功能完善(用户角色权限),此为框架平台,文档、注释齐全,专门供程序员二次开发 所有前端后台代码封装过后十分精简易上手,出错概率低。 同时支持移动客户端访问。 核心框架:Spring Boot 权限框架:Apache ...

    SpringMVC+Mybatis 框架,非Mven版本,自带基本功能和教复杂的表单样例

    自己搞的,赚点积分。下载的人,不会觉得亏。亏了私信我。 【前端框架】 基于bootstrap的AdminLte2.4 ...2、封装了可配置的Quartz定时器;分两个版本:一个基于xml的配置版,一个是读取SQL 3、轻量级缓存 4、页面优美。

    SSM,crm项目

    定时器,java内存缓存,ssm流程,spring jdbc配置文件,解析ip地址、组装ip工具类、日期工具类、md5加密、数据分页、反射工具、消息、封装、字符转换

    安卓java读取网页源码-python-demo:Python演示

    安卓java读取网页源码 1、本项目可以实现如下功能: A、那种在后台默默运行的定时器(比较适合数据采集) B、搭建restful接口的web服务器(spring...5、cron:定时器相关使用(spring boot的 @Scheduled(cron = "0 */10

    基于SpringBoot+Vue开发的前后端分离外卖点单系统源码+数据库+项目说明.zip

    - 提供CrudService接口,对增删改查进行封装,代码更简洁 - 页面交互使用Vue2.x,极大的提高了开发效率 - 完善的部门管理及数据权限,通过注解实现数据权限的控制 - 完善的XSS防范及脚本过滤,彻底杜绝XSS攻击 - ...

    JAVA上百实例源码以及开源项目源代码

    像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java编写的显示器显示模式检测程序 2个目标文件 内容...

    JAVA上百实例源码以及开源项目

    像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java编写的显示器显示模式检测程序 2个目标文件 内容...

Global site tag (gtag.js) - Google Analytics