Quarzt使用MethodInvokingJobDetailFactoryBean扩展

Quarzt创建定时任务,在xml文件中,配置任务有两种方式

  1. MethodInvokingJobDetailFactoryBean

  2. JobDetailFactoryBean

1的方式,使用实现类和一个无参的方法,无侵入。

2需要创建job类,继承org.quartz.Job类

现在一般系统部署为集群模式,定时任务可能在多台机器上执行,为避免重复执行,有一下几种方式

系统中对数据加锁
选定机器执行某项任务
使用quarzt集群配置

MethodInvokingJobDetailFactoryBean

配置xml任务,若有多个任务需要调度,则配置多个JobDetail、Trigger即可

<bean id="testTask" class="com.alisoft.xx.TestTask" />
<bean id="xxJobDetail"    
	class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">    
    <property name="concurrent">        
        <value>false</value>        
    </property>    
    <property name="targetObject">        
        <ref bean="testTask"/>        
    </property>    
    <property name="targetMethod">        
        <value>execute</value>        
    </property>    
</bean>
<!-- SimpleTriggerBean可以用org.springframework.scheduling.quartz.CronTriggerBean代替 -->
<bean id="xxTriggerBean" class="org.springframework.scheduling.quartz.SimpleTriggerBean">    
    <property name="jobDetail">        
        <ref bean="xxJobDetail"/>        
    </property>    
    <property name="startDelay">        
        <value>1000</value>        
    </property>    
    <property name="repeatInterval">        
        <value>60000</value>        
    </property>    
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">    
    <property name="triggers">        
        <list>            
            <ref local="xxTriggerBean"/>            
        </list>        
    </property>    
</bean>

但是在我们现实项目中,仅仅完成这样的功能是还不够的,我们还需要争取完成以下几点:

1.对所有的Task实现执行开始、结束时间等相关信息的记录;
2.对每天的Task执行结果持久化、或者通过email、旺旺消息等方式告知相关owner;
3.当我们有多台Task服务器时,如何保证每个任务只在一台服务器上执行;

针对以上几个问题,我们也都有很简单、直接的办法可以搞定。

问题解决存在问题
1,2每个任务中各自编码完成每个task都要写非常类似的重复代码
3通过配置来完成向不同task服务器部署不一样的发布包来完成多少台task服务器,就需要通过修改配置重新打包并发布多少次

其实我们可以利用Spring默认提供的AOP来非常优雅的解决这几个问题:

扩展MethodInvokingJobDetailFactoryBean来实现对任务调度时的拦截

重写关键方法executeInternal(JobExecutionContext context)

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
	}
}

将自定义JobDetailFactoryBean的bean配置设置为abstract,从而减少每个task的相关配置量,新的代码可参考如下配置:

<bean id="appsAbstractJobDetail" class="com.alisoft...AppsMethodInvokingJobDetailFactoryBean" 
	abstract="true">  
    <property name="concurrent" value="false" />  
    <property name="targetMethod" value="execute" />  
</bean>

<bean id="testTaskHandler" class="com.alisoft...task.TestTaskHandler" />
<bean id="testTaskJobDetail" parent="appsAbstractJobDetail">  
    <property name="targetObject" ref="testTaskHandler" />  
</bean>

<bean id="testTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
    <property name="jobDetail" ref="testTaskJobDetail" />  
    <property name="cronExpression" value="0 10 0 * * ?" />  
</bean>

转载出处https://www.xuebuyuan.com/641793.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值