可调控的定时任务——quartz

1 篇文章 0 订阅

好久没写博客了,一个懒字让我停顿了这么久。。进入正题

需求:可自由增加、修改、删除定时任务,项目启动事需要执行一次定时任务

  1. 这里我用的是quartz-2.2.1.jar,spring是3.2版本
  2. 对于定时任务quartz我的了解也不多,有很多都是代码的搬运以及调整,对于quartz这一块,我只知道怎么用,还需要进一步学习,慢慢来吧。
  3. 在这之前,要考虑自己需要什么东西,其一:quartz的xml配置文件,其二:一个定时任务执行类,其三:既然是可自有增加修改删除,还需要一个管理类。一共是两个类+一个配置文件。

xml配置文件

<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     			http://www.springframework.org/schema/context 
     			http://www.springframework.org/schema/context/spring-context-3.0.xsd"
    default-lazy-init="true">
<!-- 这个类就是需要做定时任务的类-->  
<bean id="MyJob" class="cn.com.yt.service.MyJob"> </bean>
    <!-- 定义调用对象和调用对象的方法,id是JobDetail的名字  -->  
    <bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
        <!-- 调用的类  -->  
        <property name="targetObject" ref="myJob" />  
        <!-- 调用类中的方法  -->  
        <property name="targetMethod" value="doSomething" />  
        <!-- 是否并发 防止锁死 -->  
        <property name ="concurrent" value ="false"  />          
    </bean>  
    <!-- 这是普通的定义触发时间,可以设置多个定时任务 -->  
<!--     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean ">   -->
<!--         <property name="jobDetail" ref="jobtask" />   -->
<!--         cron表达式    -->
<!--         <property name="cronExpression" value="0/1 * * * * ?" />   -->
<!--     </bean>   -->
	<!-- 这里设置的是项目启动执行一次定时任务  -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="jobtask"   />
        <!-- 启动延迟,毫秒 -->
        <property name="startDelay" value="5000" />
        <!-- 重复次数 0即只执行一次-->
        <property name="repeatCount" value="0" />
    </bean>

    <!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  
    	将quartz加入到了spring中后,ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化
    	 lazy-init="false" 立退加载, 表示spring启动时,立刻进行实例化。
    	  (lazy-init 设置只对scop属性为singleton的bean起作用)
    	 lazy-init="true" 延迟加载 ,设置为lazy的bean将不会在ApplicationContext启动时提前被实例化,而是在第一次向容器通过getBean索取bean时实例化的。
    	 如果没有这个配置的话,项目启动则不会执行定时任务
    	-->  
    <bean id="startQuertz" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="triggers">  
            <list>  
                <ref bean="cronTrigger" />  
            </list>  
        </property>  
    </bean>  
</beans>  

定时任务管理类

这个类写的不好,很多变量其实可以当做公共变量来用

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;

public class QuartzManager {

	
	private Logger logger = Logger.getLogger(QuartzManager.class);
	private StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
    private Scheduler scheduler ;

    /** 
     * @Description: 添加一个定时任务 
     *  
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置,参考quartz说明文档  
     */  
    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public void addJob(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class jobClass, String cron) {  
    	
        try {
        	scheduler = schedulerFactory.getScheduler();
            // 任务名,任务组,任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
            // 触发器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger
            scheduler.scheduleJob(jobDetail, trigger);  
            
            // 启动  
            if (!scheduler.isShutdown()) {  
            	logger.info("创建quartz任务成功:任务组名:" + jobGroupName +",任务名:"+jobName + ",触发器组名:"+ 
            			triggerGroupName + ",触发器名:" + triggerName + ",cron:" + cron);
            	scheduler.start();  
            }  
        } catch (Exception e) {
        	logger.error("创建quartz任务失败:任务组名:" + jobGroupName +",任务名:"+jobName + ",触发器组名:" + 
        			triggerGroupName + ",触发器名:" + triggerName+ ",cron:" + cron);
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description: 修改一个任务的触发时间
     *  
     * @param jobName 
     * @param jobGroupName
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名 
     * @param cron   时间设置
     */  
    public void modifyJobTime(String jobName, 
            String jobGroupName, String triggerName, String triggerGroupName, String cron) {
        try {  
        	scheduler = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }  

            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(cron)) { 
                /** 方式一 :调用 rescheduleJob 开始 */
                // 触发器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组  
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一个任务的触发时间
                scheduler.rescheduleJob(triggerKey, trigger);
                logger.info("修改quartz任务成功:任务组名:" + jobGroupName +",任务名:"+jobName + ",触发器组名:"+ 
            			triggerGroupName + ",触发器名:" + triggerName + ",cron:" + cron);
                /** 方式一 :调用 rescheduleJob 结束 */

                /** 方式二:先删除,然后在创建一个新的Job  */
                //JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
                //Class<? extends Job> jobClass = jobDetail.getJobClass();  
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
                /** 方式二 :先删除,然后在创建一个新的Job */
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description: 移除一个任务 
     *  
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) {
        try {  
        	scheduler = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

            scheduler.pauseTrigger(triggerKey);// 停止触发器  
            scheduler.unscheduleJob(triggerKey);// 移除触发器  
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
            logger.info("移除任务:[jobName]:" + jobName + ",[jobGroupName]" + jobGroupName );
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:启动所有定时任务 
     */  
    public void startJobs() {
        try {  
        	scheduler = schedulerFactory.getScheduler();
            scheduler.start();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    /**
     * 判断定时任务是否存在
     * @param name 任务名
     * @return 如果存在任务返回true
     * 
     * triggerState状态  
     * BLOCKED 阻塞
     * COMPLETE 完成
     * COMPLETE 出错
     * ERROR 不存在
     * NORMAL 正常
     * PAUSED 暂停
     * 
     */
    public boolean exist(String name,String group){
    	try {
			scheduler = schedulerFactory.getScheduler();
			Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(group));
			for(JobKey jobKey : jobKeys){
				if(jobKey.getName().equals(name)){
					TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
					TriggerState triggerState = scheduler.getTriggerState(triggerKey);
					System.out.println(triggerState);
					logger.info("任务存在:[jobname]:" + name);
					return true;
				}
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	logger.info("任务不存在:[jobname]:" + name);
    	return false;
    }
       /**
     * 获取到所有运行中的job
     */
    @SuppressWarnings("unchecked")
	public void getAllJobs(){
    	try {
			scheduler = schedulerFactory.getScheduler();
			for(String groupName : scheduler.getJobGroupNames()){
				for(JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))){
					String jobName = jobKey.getName();
					String jobGroup = jobKey.getGroup();
					List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
					//下一次执行时间
					Date nextFireTime = triggers.get(0).getNextFireTime();
					System.out.println("运行中任务:[jobName]:" + jobName + ",[groupName]:" + jobGroup + "-" + nextFireTime);
				}
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
  
    public Scheduler getScheduler() {
        return scheduler;
    }
    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }  
}

任务执行类

在这里是用户将执行任务的时间添加到了数据库中,项目启动时执行一次此类,从而添加一个定时任务到系统中。Myjob2和MyJob3是两个不同的任务类。这里要注意一点,Myjob类已经添加到了配置文件中,但是Myjob2和Myjob3并没有,所有这两个来要实现org.quartz.Job接口。

/**
 * job服务类
 * 项目启动时从数据库中查找可执行任务
 */
public class MyJob{

	private Logger logger = Logger.getLogger(MyJob.class);
	
	public void doSomething(){
		CocAndZfkService service = (CocAndZfkService) ContextUtil.getBean("CocAndZfkService");
		List<TblAutoImport> allPath = service.getAllPath();
		List<TblInventoryThan> allJob = service.getAllJob();
		QuartzManager quartzManager = new QuartzManager();
		int count = 0;
		for (TblAutoImport tblAutoImport : allPath) {
			String name = tblAutoImport.getOperator() + tblAutoImport.getId();
			String[] split = tblAutoImport.getAutoTime().split(":");
			String cron = split[2] + " " + split[1] + " " + split[0] + " * * ?";
			quartzManager.addJob(name, name, name, name, MyJob2.class, cron);
			count++;
		}
		for(TblInventoryThan tblInventoryThan : allJob){
			String name = tblInventoryThan.getOperator() + tblInventoryThan.getId();
			String[] split = tblInventoryThan.getAutoTime().split(":");
			String cron = split[2] + " " + split[1] + " " + split[0] + " * * ?";
			quartzManager.addJob(name, name, name, name, MyJob3.class, cron);
			count++;
		}
		logger.info("定时任务启动:共添加了" + count + "条定时任务");
	}
}

使用quartz中的疑惑,还未解决

当你的定时任务启动后,你会发现你无法调用spring上下文中的内容,会什么都得不到,上网查找了一些资料,说quartz启动后,是在另外一个独立的线程中运行,所以得不到spring上下文中的东西,例如用户的一些信息。百度了好些方法,还是得不到,望看到文章的大佬能指点一二,万分谢谢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值