Quartz中扩展MethodInvokingJobDetailFactoryBean实现...
来源:百度文库 编辑:神马文学网 时间:2024/04/28 04:45:18
利用Quartz来实现对任务的调度已经被广泛地应用了,一个利用Quartz来进行任务调度的典型配置如下:
view plaincopy to clipboardprint?
- class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
false execute -
-
-
1000 -
-
60000 -
-
若有多个任务需要调度,则配置多个JobDetail、Trigger即可,待执行的Task bean没有啥任何要求,不需要extends任何class、或者implements任何interface,只是被执行的method需要是无参数的;
但是在我们现实项目中,仅仅完成这样的功能是还不够的,我们还需要争取完成以下几点:
- 对所有的Task实现执行开始、结束时间的记录;
- 对每天的Task执行结果持久化、或者通过email、旺旺消息等方式告知相关owner;
- 当我们有多台Task服务器时,如何保证每个任务只在一台服务器上执行;
针对以上几个问题,我们也都有很简单、直接的办法可以搞定,比如说1、2两点可以直接在每个任务中各自编码完成,但是这样不仅每个task都要写非常类似的重复代码、而且不能保证每个任务的执行情况都被记录,因为某些task的编码人员就不会在意这些非功能性需求;对于第3点,我们也可以通过配置来完成向不同task服务器部署不一样的发布包来完成,但这给发布带来了麻烦,这意味着有多少台task服务器,就需要通过修改配置重新打包并发布多少次;
其实我们可以利用Spring默认提供的AOP来非常优雅的解决这几个问题:扩展MethodInvokingJobDetailFactoryBean来实现对任务调度时的拦截!其关键代码为MethodInvokingJobDetailFactoryBean.MethodInvokingJob.executeInternal(JobExecutionContext context);这个method中;
具体步骤如下:
- 新增所有Task都需要实现的interface,可参考如下代码:
view plaincopy to clipboardprint?- public interface TaskHandler {
- /**
- * 任务调度执行需要实现的method
- */
- TaskResult execute();
- }
- 基于MethodInvokingJobDetailFactoryBean实现自定义的JobDetailFactoryBean,在具体执行待调度任务的method前后加入公用逻辑,比如记录开始、结束日期、判断该task是否由该台服务器执行、任务执行完成之后将运行结果进行持久化或者发email等给相关owner;可参考如下代码:
view plaincopy to clipboardprint?- public class AppsMethodInvokingJobDetailFactoryBean extends
- MethodInvokingJobDetailFactoryBean {
- protected static final Log logger = LogFactory.getLog(AppsMethodInvokingJobDetailFactoryBean.class);
- /* (non-Javadoc)
- * @see org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean#afterPropertiesSet()
- */
- @Override
- public void afterPropertiesSet() throws ClassNotFoundException,
- NoSuchMethodException {
- super.afterPropertiesSet();
- logger.info("origin jobClass : " + ((JobDetail)super.getObject()).getJobClass().getName());
- // Consider the concurrent flag to choose between stateful and stateless job.
- if(MethodInvokingJob.class.getName().equals(((JobDetail)super.getObject()).getJobClass().getName())) {
- ((JobDetail)super.getObject()).setJobClass(AppsMethodInvokingJob.class);
- } else {
- ((JobDetail)super.getObject()).setJobClass(AppsStatefulMethodInvokingJob.class);
- }
- logger.info("new jobClass : " + ((JobDetail)super.getObject()).getJobClass().getName());
- }
- public static class AppsMethodInvokingJob extends MethodInvokingJob {
- protected static final Log logger = LogFactory.getLog(AppsMethodInvokingJob.class);
- private MethodInvoker methodInvoker;
- private String errorMessage;
- /**
- * Set the MethodInvoker to use.
- */
- public void setMethodInvoker(MethodInvoker methodInvoker) {
- this.methodInvoker = methodInvoker;
- this.errorMessage = "Could not invoke method '" + this.methodInvoker.getTargetMethod() +
- "' on target object [" + this.methodInvoker.getTargetObject() + "]";
- }
- /**
- * Invoke the method via the MethodInvoker.
- */
- protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
- Date startDate = new Date();
- String taskName = methodInvoker.getTargetClass().getName();
- TaskResult taskResult;
- try {
- if (logger.isInfoEnabled()) {
- logger.info(taskName + " job start at " + startDate);
- }
- //根据当前服务器主机名或者IP判断是否需要执行该任务
- //TODO Code
- //调用具体task执行method代码
- taskResult = this.methodInvoker.invoke();
- } catch (Exception ex) {
- logger.error(taskName + " accounted a error : " + this.errorMessage, ex);
- throw new JobExecutionException(this.errorMessage, ex, false);
- } finally {
- if(logger.isInfoEnabled()) {
- logger.info(taskName + " job end at " + new Date());
- }
- //将task执行结果taskResult进行持久化、或者通知相关owner
- //TODO Code
- }
- }
- }
- public static class AppsStatefulMethodInvokingJob extends AppsMethodInvokingJob {
- }
- }
- 将自定义JobDetailFactoryBean的bean配置设置为abstract,从而减少每个task的相关配置量,新的代码可参考如下配置:
view plaincopy to clipboardprint?- abstract="true">
-
-
-
Quartz中扩展MethodInvokingJobDetailFactoryBean实现...
一步一步实现MFC扩展DLL中导出类和对话框
Spring中Quartz配置 - - JavaEye技术网站c
用Shell扩展实现源代码统计程序
扩展JAAS实现类实例级授权
扩展JAAS实现类实例级授权(ZZ)
SQL Server扩展存储过程实现远程备份与恢复
oracle中实现分页
--Quartz Cron Expression
Quartz的cron表达式
外媒:解放军将中亚军演显扩展海外雄心
如何在图层增加点线面(不通过扩展MapComponent类实现
PHP的GZIP压缩页面例子,使用zlib扩展实现页面GZIP压缩输出
flex特效(3):扩展基本控件实现一个自定义图标的导航树
在oracle中实现分页
Spring中实现文件上传
在JSF中实现分页
Delphi中PING的实现
VB中实现“所见即所得”功能
quartz 在WEB中应用小结 - My english is poor,but I am happy to speak my poor english! - JavaEye技术网站
Quartz从入门到进阶
如何在 JavaScript 中实现拖放(中)
SQL Server中未公布的访问注册表的扩展存储过程
中移动收购Paktel全部股权 将扩展在巴网络