Spring+ quartz 之 多任务动态定时(任务中起任务)

 

参见上一篇Spring+ quartz 多任务定时 执行 与cronExpression表达式 可以知道如何设置多个规则的定时任务,但有时需要客户自己设置指定的时间来启动新的任务处理不同的事情。

 

     实现方式:用户在前台自行维护任务列表和任务执行时间,后台将任务执行时间解析成对应的cronexpression后与任务列表一起保存到数据库中。在 服务器运行期间添加的任务通过验证的(quartz会验证cronexpression是否合法以及对应时间是否已经过期)将直接添加一个任务以及触发器。

 

    简而言之,就是自己创建一个新的jobdetail ---新的 Trigger 指定行的定时规则--启动新增定时器任务  (执行完新任务可以选择取消新的任务)

这里实现的思路是:按照定时规则扫描用户设置的任务开始时间,如定时发短信,有定时的就发出去。

 

1、首先加入定时规则扫描的任务,

 

 

package net.nilm61.timeTask;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import net.nilm61.entity.Repay;
import net.nilm61.service.RepayService;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;



public class AutoRepayBidTask extends QuartzJobBean{

	
	private RepayService repayService;
	
	public void setRepayService(RepayService repayService) {
		this.repayService = repayService;
	}
	
	@Override
	protected void executeInternal(JobExecutionContext context)
			throws JobExecutionException {
		 EntityManagerFactory emf = null;
		    EntityManager em = null;
		
		//System.out.println("Start!!!!!!!!!");
		try{
			Scheduler  scheduler = context.getScheduler();
			ApplicationContext ac = (ApplicationContext)scheduler.getContext().get("theScheduler");
			
			  emf = (EntityManagerFactory) ac.getBean("entityManagerFactory", EntityManagerFactory.class);
		      em = emf.createEntityManager();
		      TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em));
			
		      
		      RepayService repayService = (RepayService)ac.getBean("recordService");
		      
		      setRepayService(repayService);
		      
		      doBiz(scheduler);
			
		}catch(Exception e){
			e.printStackTrace();
			//logger.error(e.getMessage());
		}finally{
			//System.out.println("over!!!!!!!!!!!!!!!!!");
			if(em!=null){
				em.close();
			}
		}
		
	}

	private void doBiz(Scheduler scheduler) {
		try{
			List<Repay>  repays = repayService.getByAutoRepay();
//从数据库中查询定时处理的条目
			if(repays != null && repays.size() >0){
				DateFormat df = new SimpleDateFormat("ss mm HH dd MM ? yyyy ",Locale.ENGLISH);
				for(Repay repay : repays){
					Date  actualTime =repay.getActualTime();
					if(actualTime != null){
						String  cronExpression = df.format(actualTime);
						
			//新建任务,任务组为默认的Scheduler.DEFAULT_GROUP,需要执行的任务类为DoBiz4TestTask.class  
						JobDetail jobDetail =  new JobDetail("AutoRepayBidsJob_" + repay.getId(), Scheduler.DEFAULT_GROUP,  
								DoBiz4TestTask.class);  
						
							CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(
									 "AutoRepayBidsTrigger_"+repay.getId(), Scheduler.DEFAULT_GROUP); 
							if(cronTrigger == null){
								//新建触发器,触发器为默认的Scheduler.DEFAULT_GROUP  
								cronTrigger = new CronTrigger("AutoRepayBidsTrigger_" + repay.getId(), Scheduler.DEFAULT_GROUP);  
							}

							//为触发器设置定时表达式  
							cronTrigger.setCronExpression(cronExpression);
							
//							System.out.println(cronExpression);
							
			                try{  
				                //启动新增定时器任务   
				                scheduler.scheduleJob(jobDetail, cronTrigger); 
			                   }catch(SchedulerException e){  
			                    //启动验证失败,设置任务标记为禁用  
			                    e.printStackTrace();  
			                }   
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
	
}

 

 

2.增加DoBiz4TestTask (具体执行的定时任务)

 

所有的触发器执行的任务类均为DoBiz4TestTask.class,DoBiz4TestTask 需要实现接口:org.quartz.Job中的方法execute方法,这里继承的是org.quartz.Job的子类org.springframework.scheduling.quartz.QuartzJobBean 参考代码如下

 

 

package net.nilm61.timeTask;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;



public class DoBiz4TestTask extends QuartzJobBean{

	@Override
	protected void executeInternal(JobExecutionContext context)
			throws JobExecutionException {
		 EntityManagerFactory emf = null;
		    EntityManager em = null;
		
		try{
			Scheduler  scheduler = context.getScheduler();
			ApplicationContext ac = (ApplicationContext)scheduler.getContext().get("theScheduler");
			
			Trigger trigger = context.getTrigger();
			  emf = (EntityManagerFactory) ac.getBean("entityManagerFactory", EntityManagerFactory.class);
		      em = emf.createEntityManager();
		      TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em));
		      
		       doBiz(scheduler,trigger);
			
		}catch(Exception e){
			e.printStackTrace();
			//logger.error(e.getMessage());
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
		
	}

	private void doBiz(Scheduler  scheduler,Trigger trigger) {
		try{
	        //获取触发器名称  
	        String triggerName = trigger.getName();  
	        //根据触发器名称得到对应的任务Id  
//	        Integer id = Integer.valueOf(triggerName.split("_")[1]);
	        //处理指定的任务
	        //TODO: ...
	        System.out.println("triggerName === "+triggerName);
	        
	        //根据触发器名称得到对应的任务Id  
            if(null != trigger){  //执行完移除该任务
                scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());  
            }  
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
	
}

 

 

3.配置文件中加入

 

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass" value="net.nilm61.timeTask.DoAutoRepayBidTask"/>
		<!-- <property name="jobDataMap" ></property> -->
</bean>
<bean id="DoBiz4TestTask" class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass" value="net.nilm61.timeTask.DoBiz4TestTask"/>
		<!-- <property name="jobDataMap" ></property> -->
</bean>


<bean id="AutoRepayTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
	<property name="jobDetail"	ref="jobDetail"/>
	<property name="cronExpression" value="0 0/1 14-18 * * ?"/>
</bean>

<bean id="DoBiz4TestTaskss" class="org.springframework.scheduling.quartz.CronTriggerBean">
	<property name="jobDetail"	ref="DoBiz4TestTask"/>
</bean>

	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="triggers">
		<list>

			<ref bean="AutoRepayTrigger"/>
		</list>
	</property>

	<property name="applicationContextSchedulerContextKey">
		<value>theScheduler</value>
	</property>
</bean>

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值