Quartz定时作业管理

本文介绍了一个基于Spring框架的定时任务管理系统,支持多种定时策略,包括每日、每周及立即执行。通过自定义类和Spring配置实现任务调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 public abstract class BaseJob {

    /**
     * 
     */
    private static final long serialVersionUID = -750342144932125596L;

    public BaseJob() {
    }

    private Job job = new Job();

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }

    private Scheduler scheduler;

    // 通过setter方法传入被调用者的实例scheduler
    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    public void reScheduleJob() throws SchedulerException, ParseException {

        MyCronTrigger trigger = (MyCronTrigger) this.getScheduler().getTrigger(
                this.getJob().getTriggerName(), Scheduler.DEFAULT_GROUP);
        this.setJob(trigger.getScheduleInfoManager().queryJobInfo(this).getJob());

        // 如果job表中的status!=P 就不启动这个job
        if (!this.getJob().getStatus().equalsIgnoreCase("P")) {
            this.getScheduler().pauseJob(this.getJob().getName(), Scheduler.DEFAULT_GROUP);
            return;
        } else {
            this.getScheduler().resumeJob(this.getJob().getName(), Scheduler.DEFAULT_GROUP);
        }

        // ConExpressionTransfer.convertDateToCro nExp(everyWhat, commonNeeds, monthlyNeeds,
        // weeklyNeeds, userDefinedNeeds);

        System.out.println("首次时间 >>>> " + trigger.getOrigTime());// 初始

        String lastCronExpression = trigger.getCronExpression(); // 上次时间
        System.out.println("上次时间 >>>> " + lastCronExpression);

        String newCronExpression = this.getJob().getRuntime();// 新时间
        System.out.println("新时间   >>>> " + newCronExpression);

        if (!lastCronExpression.equalsIgnoreCase(newCronExpression)) {
            System.out.println(" ..时间有变化...从  " + lastCronExpression + " 到 " + newCronExpression);
            System.out.println(" 重置 CronExpression ");
            trigger.setCronExpression(newCronExpression);
            this.getScheduler().rescheduleJob(this.getJob().getTriggerName(),
                    Scheduler.DEFAULT_GROUP, trigger);
        } else {
            // 下面是执行具体的job内容
            System.out.println(" ..时间没有变化...");
            this.execute();
        }
    }

    public abstract void execute();
}

 

public class PrintJob extends BaseJob {

    public PrintJob() {
        super();
        this.getJob().setTriggerName("printJobTrigger");
        JobRegistry.registerJob(this);
    }

    @Override
    public void execute() { // 执行入口函数
        // 业务逻辑
        System.out.println("PrintJOB over = " + DateTimeUtil.currentTime());
        System.out.println(JobRegistry.getJob("printJobTrigger").getJob().getTriggerName());
    }

}

 

所有要执行的job都必须来这里注册
public class JobRegistry {

    /*
     * Map<jobTriggerName,BaseJob>
     */
    private static Map<String, BaseJob> jobMap = new HashMap<String, BaseJob>();

    public static void registerJob(BaseJob job) {
        jobMap.put(job.getJob().getTriggerName(), job);
    }

    public static BaseJob getJob(String triggerName) {
        return jobMap.get(triggerName);
    }
}

 

public class MyCronTrigger extends CronTriggerBean {

    private BaseJob job;
    public BaseJob getJob() {
        return job;
    }

    public void setJob(BaseJob job) {
        this.job = job;
    }

    private ScheduleInfoManager scheduleInfoManager;

    public ScheduleInfoManager getScheduleInfoManager() {
        return scheduleInfoManager;
    }

    // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager
    public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager) {
        System.out.println("InitializingCronTrigger.........");

        this.scheduleInfoManager = scheduleInfoManager;
        String cronExpression = scheduleInfoManager.queryJobInfo(job).getJob().getRuntime();
        this.origTime = cronExpression;
        try {
            System.out.println(cronExpression);
            setCronExpression(cronExpression);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    private String origTime;

    public String getOrigTime() {
        return origTime;
    }
    /**
     * @param origTime the origTime to set
     */
    public void setOrigTime(String origTime) {
        this.origTime = origTime;
    }
}

 

 /**
     * 获取任务时间
     * 
     * @return
     */
    protected String getRuntime() {

        HttpServletRequest request = ServletActionContext.getRequest();
        String everyWhat = request.getParameter("everyWhat");
        if ("Immediate Processing".equals(everyWhat)) {
            System.out.println("立即执行。。。。");
            String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
            String[] commonNeeds = { time.split(":")[2], time.split(":")[1], time.split(":")[0] };
            String userDefinedNeeds = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String[] monthlyNeeds = { request.getParameter("week"),
                request.getParameter("dayOfWeek") };
            String weeklyNeeds = (String) request.getParameter("dayOfWeek");
            cronExpression = CronExpConversion.convertDateToCronExp(everyWhat, commonNeeds,
                    monthlyNeeds, weeklyNeeds, userDefinedNeeds);
        } else {
            String time = request.getParameter("time");
            String[] commonNeeds = { time.split(":")[2], time.split(":")[1], time.split(":")[0] };
            String[] monthlyNeeds = { request.getParameter("week"),
                request.getParameter("dayOfWeek") };
            String weeklyNeeds = (String) request.getParameter("dayOfWeek");
            String userDefinedNeeds = request.getParameter("date");
            cronExpression = CronExpConversion.convertDateToCronExp(everyWhat, commonNeeds,
                    monthlyNeeds, weeklyNeeds, userDefinedNeeds);
        }
        return cronExpression;
    }

 

public class CronExpConversion {

    /**
     * 页面设置转为UNIX cron expressions 转换算法
     * 
     * @param everyWhat
     * @param commonNeeds 包括 second minute hour
     * @param monthlyNeeds 包括 第几个星期 星期几
     * @param weeklyNeeds 包括 星期几
     * @param userDefinedNeeds 包括具体时间点
     * @return cron expression
     */
    public static String convertDateToCronExp(String everyWhat, String[] commonNeeds,
                                              String[] monthlyNeeds, String weeklyNeeds,
                                              String userDefinedNeeds) {
        String cronEx = "";
        String commons = commonNeeds[0] + " " + commonNeeds[1] + " " + commonNeeds[2] + " ";
        String dayOfWeek = "";
        if ("weekly".equals(everyWhat)) {
            dayOfWeek = weeklyNeeds; // 1
            if (dayOfWeek != null) {
                cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " "
                        + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " "
                        + dayOfWeek + " ").trim();
            } else {
                cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " "
                        + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " "
                        + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " ").trim();
            }
        } else if ("Daily".equals(everyWhat)) {
            cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " "
                    + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " "
                    + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " ").trim();
        } else {// 立即执行--将定时任务的时间设置为当前时间
            String dayOfMonth = userDefinedNeeds.split("-")[2];
            if (dayOfMonth.startsWith("0")) {
                dayOfMonth = dayOfMonth.replaceFirst("0", "");
            }
            String month = userDefinedNeeds.split("-")[1];
            if (month.startsWith("0")) {
                month = month.replaceFirst("0", "");
            }
            String year = userDefinedNeeds.split("-")[0];
            // FIXME 暂时不加年份 Quartz报错
            /*
             * cronEx = (commons + dayOfMonth + " " + month + " " +
             * CronExRelated.specialCharacters.get(CronExRelated._ANY) + " " + year).trim();
             */
            cronEx = (commons + dayOfMonth + " " + month + " "
                    + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " ").trim();
        }
        System.out.println(cronEx);
        return cronEx;
    }
}

 

public class CronExRelated {
    public static final String _EVERY = "every";
    public static final String _ANY = "any";
    public static final String _RANGES = "ranges";
    public static final String _INCREMENTS = "increments";
    public static final String _ADDITIONAL = "additional";
    public static final String _LAST = "last";
    public static final String _WEEKDAY = "weekday";
    public static final String _THENTH = "theNth";
    public static final String _CALENDAR = "calendar";

    public static final String _TYPE = "type";

    /**
     * 0 0 6 ? * 1#1 ? monthly; 0 0 6 ? * 1 ? weekly; 0 0 6 30 7 ? 2006 useDefined
     */
    static String[] headTitle = { "TYPE", "SECONDS", "MINUTES", "HOURS", "DAYOFMONTH", "MONTH",
        "DAYOFWEEK", "YEAR" };

    /**
     * cron expression special characters Map specialCharacters
     */
    public static Map specialCharacters;

    static {
        specialCharacters = new HashMap(10);
        specialCharacters.put(_EVERY, "*");// * 代表任意合法的字段
        specialCharacters.put(_ANY, "?");// ? 表示没值被指定 ,只能出现在月和星期的字段
        specialCharacters.put(_RANGES, "-");// - 表示值的范围
        specialCharacters.put(_INCREMENTS, "/");// / 表示时间的增量
        specialCharacters.put(_ADDITIONAL, ",");// 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发
        specialCharacters.put(_LAST, "L");// L 如果用在"一月哪天"段上,表示一个月的最后一天;如果用在"星期"段上。表示一个星期的最后一天(星期六)
        specialCharacters.put(_WEEKDAY, "W");// W 表示最靠近给定时间的一天,(必须是星期一到星期五)
        specialCharacters.put(_THENTH, "#");// 只能出现在"星期"段位置 ,表示第几个星期
        specialCharacters.put(_CALENDAR, "C");

        specialCharacters.put(_TYPE, headTitle);
    }

    public static void set(String ex, int index) {
        ((String[]) specialCharacters.get(_TYPE))[index] = ex;
    }
}

 

public class ScheduleInfoManager extends JpaDaoSupport {

    //把资源表中所有数据载入
    public BaseJob queryJobInfo(BaseJob baseJob){
        //String sql = "select * from JOB where TriggerName='"+ baseJob.getJob().getTriggerName() +"' and status='P'";
        String sql = "select * from JOB where TriggerName='"+ baseJob.getJob().getTriggerName() +"'";
        Query query = this.getEntityManager().createNativeQuery(sql,Job.class);
        
        //执行查询,返回的是查询的集合        
        @SuppressWarnings("unchecked")
        List<Job> jobList = query.getResultList();
        baseJob.setJob(jobList.get(0));
        System.out.println(jobList.get(0));
        return baseJob;
    } 
}

 

    /**
     * 将页面设置的时间转换为Quartz需要的时间格式并启动任务
     * 
     * @return
     */
    public String setTaskTime() {
        // 格式化后quartz的时间
        cronExpression = getRuntime();
        // 根据id获取job
        job = jobService.selectByID(Job.class, job.getId());
        // 修改job的运行时间
        job.setRuntime(cronExpression);
        // 更新job
        jobService.update(job);
        System.out.println("启动任务。。。");
        BaseJob baseJob = JobRegistry.getJob(job.getTriggerName());
        try {
            baseJob.reScheduleJob();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(cronExpression);
        return null;
    }

 

<?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">
	<context:annotation-config/>

	<bean id="scheduleInfoManager" class="cn.com.acca.sas.jobManager.app.service.ScheduleInfoManager"></bean>
	 
    <bean id="printJob" class="cn.com.acca.sas.jobManager.app.job.PrintJob">
    	<property name="scheduler" ref="printJobScheduler" />
    </bean>

	<bean id="printJobInvoke" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
	    <property name="targetObject" ref="printJob"/>
        <property name="targetMethod" value="reScheduleJob"/>  
        <property name="concurrent" value="false" />
	</bean>

	<bean id="printJobTrigger" class="cn.com.acca.sas.jobManager.app.service.MyCronTrigger"> 
		<property name="job" ref="printJob" /> 
        <property name="jobDetail" ref="printJobInvoke" />
        <property name="scheduleInfoManager" ref="scheduleInfoManager"/>
	</bean>
	
	<bean id="printJobScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
           <list>
                <ref local="printJobTrigger" />
           </list>
        </property>
    </bean>	
    
    
    
    <!-- 触发器将告诉Quartz两件事:在何时触发任务、触发哪个任务。
    	 cronExpression为调度时间,格式和unix上的crontab类似:"0-5 10,44 14 ? 3 5 2012" 2012年3月某日的星期五14:10和14:44时的1-5秒触发 。其中问号表示忽略该位置(星期)上的值。
    	 jobDetail指向具体的任务调用bean:jobInvoker。如果有多个任务,每个任务的触发时间都不一样,则可以在此配置多个不同的触发器。
	-->

</beans>

 

改定时作业只要实现了三种策略:
1.每天xx点执行
2.每周的xx星期xx点执行
3.立即执行

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值