spring+quartz实现动态任务调度

上一篇说过怎么在项目中部署quartz,这节主要说说怎么动态获取数据库的任务进行调度。
关于怎么吧任务存进数据库,取出这都是基本的增删。本篇忽略。

在说今天内容前 先说一个注解@PostConstruct这个是在servlet启动时,就执行的注解。为什么要说他呢?我们项目很多任务是配置在数据库的,所以我们启动项目的时候就要直接执行这些任务。所以要这个注解。

直接上代码

public class SysJob {
    private Long jobId;         //主键
    private String jobName;     //任务名称
    private String jobGroup;    //任务分组
    private String jobBeanName; //任务类型
    private String cronExpr;    //CRON表达式
    private String inParam;     //任务参数
    private int currState;      //当前状态 当前状态(0未启动1已启动)
    private int isAutoStart;    //是否随工程启动 (0不随工程启动1随工程启动)
    private String ipAddr;      //服务器IP地址
    private int isDel;          //是否删除 (0未删除1已删除)
    private String jobMemo;     //备注
    private long staffId;       //创建人
    private String staffName;   //创建人
    private String createTime;  //创建时间

    public String getStaffName() {
        return staffName;
    }
    public void setStaffName(String staffName) {
        this.staffName = staffName;
    }
    private String lastModTime; //最后修改时间

    public Long getJobId() {
        return jobId;
    }
    public void setJobId(Long jobId) {
        this.jobId = jobId;
    }
    public String getJobName() {
        return jobName;
    }
    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
    public String getJobBeanName() {
        return jobBeanName;
    }
    public void setJobBeanName(String jobBeanName) {
        this.jobBeanName = jobBeanName;
    }
    public String getCronExpr() {
        return cronExpr;
    }
    public void setCronExpr(String cronExpr) {
        this.cronExpr = cronExpr;
    }
    public int getCurrState() {
        return currState;
    }
    public void setCurrState(int currState) {
        this.currState = currState;
    }
    public int getIsAutoStart() {
        return isAutoStart;
    }
    public void setIsAutoStart(int isAutoStart) {
        this.isAutoStart = isAutoStart;
    }
    public int getIsDel() {
        return isDel;
    }
    public void setIsDel(int isDel) {
        this.isDel = isDel;
    }
    public String getJobMemo() {
        return jobMemo;
    }
    public void setJobMemo(String jobMemo) {
        this.jobMemo = jobMemo;
    }
    public long getStaffId() {
        return staffId;
    }
    public void setStaffId(long staffId) {
        this.staffId = staffId;
    }
    public String getCreateTime() {
        return createTime;
    }
    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    public String getLastModTime() {
        return lastModTime;
    }
    public void setLastModTime(String lastModTime) {
        this.lastModTime = lastModTime;
    }
    public String getIpAddr() {
        return ipAddr;
    }
    public void setIpAddr(String ipAddr) {
        this.ipAddr = ipAddr;
    }
    public String getInParam() {
        return inParam;
    }
    public void setInParam(String inParam) {
        this.inParam = inParam;
    }
    public String getJobGroup() {
        return jobGroup;
    }
    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

}
    /**
     * servlet上下文
     * 是为了把我们调度工厂放进去
     */
    private ServletContext servletContext;

    /**
     * 实现ServletContextAware接口的方法,注入ServletContext,本类实现这个接口
     * @param servletContext
     */
    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext =servletContext;
    }
    /**
     * bean初始化好之后执行(初始化需要随工程启动而启动的定时任务)
     */
    @PostConstruct
    public void  init() {

            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            Scheduler scheduler = null;
            //本机所有ip地址(多网卡,ip用逗号分割)本机只能启动本机设置的job
            String ips = getAllLocalHostIP();

            try {
                //设置全局的scheduler
                scheduler = schedulerFactory.getScheduler();
                servletContext.setAttribute("scheduler", scheduler);
                //启动需要随工程启动而启动的定时任务列表
                List jobList = sysJobService.getAutoStartJob();
                if(null!=jobList) {
                    for(SysJob sysJob: jobList) {
                        //比对配置的ip是否在本机ip串中,是的话,在本机启动此任务
                        if(ips.indexOf(sysJob.getIpAddr()) != -1) {
                            startTask(sysJob);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

    }

    /**
     * 返回ip地址(如果是多网卡,ip地址用逗号分割)
     * @return
     */
    public String getAllLocalHostIP() {

        StringBuilder sb = new StringBuilder("");
        try {
            String hostName = getLocalHostName();
            if (hostName.length() > 0) {
                InetAddress[] addrs = InetAddress.getAllByName(hostName);
                if (addrs.length > 0) {
                    for (int i = 0; i < addrs.length; i++) {
                        sb.append(addrs[i].getHostAddress());
                        sb.append(",");
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
/**
     * 启动任务
     * @param sysJob 定时任务对象
     * @return
     */
    public Map startTask(SysJob sysJob) {

        LOG.info("在IP:"+sysJob.getIpAddr()+":启动任务:"+sysJob.getJobName());
        Scheduler scheduler = (Scheduler) servletContext.getAttribute("scheduler");

        Map map = new HashMap();
        Boolean flag = null;
        String failCause = "";

        String jobName = sysJob.getJobId() + "_timer_job";
        String groupName = sysJob.getJobGroup();
        String triggerName = sysJob.getJobId() + "_timer_trigger";

        JobDetail job = JobBuilder.newJob(TimerJob.class).withIdentity(jobName, groupName).build();
        job.getJobDataMap().put("sysJob", sysJob);
        CronTrigger trigger = null;

        try {
            //利用框架自身的异常验证cron表达式
            trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, groupName) 
                    .withSchedule(CronScheduleBuilder.cronSchedule(sysJob.getCronExpr())).build();

        } catch (Exception e) {
            e.printStackTrace();
            map.put("flag", false);
            map.put("failCause", "非法的cron表达式!");
            return map;
        }

        try {
            if(scheduler.checkExists(JobKey.jobKey(jobName, groupName))) {
                map.put("flag", false);
                map.put("failCause", "已经被启动!");
                //防止数据库中任务状态与内存中不一致
                sysJobService.updateCurrentState(sysJob.getJobId(), 1);
                return map;
            }

            scheduler.scheduleJob(job, trigger);
            scheduler.start();
            flag = true;
            //0表示定时任务的当前状态为停止,1表示定时任务的当前状态是运行
            sysJobService.updateCurrentState(sysJob.getJobId(), 1);
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
            failCause = "未知异常,启动失败!";
        }

        map.put("flag", flag);
        map.put("failCause", failCause);
        return map;
    }
/**
     * 停止任务
     * @param sysJob 定时任务对象
     * @return
     */
    public Map<String, Object> stopTask(SysJob sysJob) {

        LOG.info("在IP:"+sysJob.getIpAddr()+":停止任务:"+sysJob.getJobName());
        Scheduler scheduler = (Scheduler) servletContext.getAttribute("scheduler");

        Map<String, Object> map = new HashMap<String, Object>();
        Boolean flag = null;
        String failCause = "";

        String jobName = sysJob.getJobId() + "_timer_job";
        String groupName = sysJob.getJobGroup();
        String triggerName = sysJob.getJobId() + "_timer_trigger";  

        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,groupName);
        JobKey jobKey = JobKey.jobKey(jobName, groupName);

        try {
            if(!scheduler.checkExists(jobKey)) {
                map.put("flag", false);
                map.put("failCause", "已经被关闭!");
                //防止数据库中任务状态与内存中不一致
                sysJobService.updateCurrentState(sysJob.getJobId(), 0);
                return map;
            }

            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);// 移除触发器
            scheduler.deleteJob(jobKey);// 删除任务
            flag = true;
            //0表示定时任务的当前状态为停止,1表示定时任务的当前状态是运行
            sysJobService.updateCurrentState(sysJob.getJobId(), 0);
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
            failCause = "未知异常,关闭失败!";
        }

        map.put("flag", flag);
        map.put("failCause", failCause);
        return map;
    }

你可能感兴趣的:(quartz)