Quartz定時調度在Web中的應用


1.在數據庫中建一個job表和job日志表

job表

job_log表

2.選用一個ORM框架,編寫一個查詢語句,查詢數據表中的所有job(略)

 

3.寫一個Quartz.java配置Quartz的相關屬性

public class QuartzJobConfig {

    //常量
    private static Scheduler sched;
    private final static String JOB_GROUP = "jobGroup";
    private final static String TRIGGER_GROUP = "triggerGroup";
    private final static Logger logger = Logger.getLogger(QuartzJobConfig.class);  //日志文件
    
    public static void registerQuartzJob() throws Exception{
        //先獲取所有的生效jobs
        @SuppressWarnings("rawtypes")
        List<Map> jobList = BaseSupport.myBatisSessionTemplate.selectList("orm.mapper.JobMapper.selectJobList");
        logger.info("總共有"+jobList.size()+"個定時任務");
        // 獲取Scheduler實例
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        sched = schedulerFactory.getScheduler();
        //在quartz里面帶上servletContext
        
        
        if(jobList!=null&&jobList.size()>0){
            for(Map job : jobList){
                try{
                    String cronExpression = getCronExpression(job);
                    JobDetail jobDetail = new JobDetail(job.get("JOB_NAME").toString(), JOB_GROUP, QuartzJobBusiness.class);
            // 觸發時間點 Trigger trigger
= new CronTrigger(job.get("ID").toString(), TRIGGER_GROUP, cronExpression); sched.scheduleJob(jobDetail, trigger); logger.info("注冊名為"+job.get("JOB_NAME").toString()+",ID為"+job.get("ID").toString()+"的任務成功"); }catch (Exception e){ e.printStackTrace(); logger.error("注冊名為"+job.get("JOB_NAME").toString()+",ID為"+job.get("ID").toString()+"的任務失敗"); } } } sched.start(); logger.info("Quartz任務注冊成功"); } private static String getCronExpression(Map job){ String cronExpression=null; //CronExpression格式:秒 分鍾 小時 天數 月 星期 年份 詳細說明 http://www.iteye.com/topic/582119 String flag = "*"; //表示所有值 不適用表達星期 String replaceFlag = "?"; // ? 號只能用在日和周域上,但是不能在這兩個域上同時使用。 String year = job.get("YEAR").toString(); String month = job.get("MONTH").toString(); String date = job.get("DATE").toString(); String day = job.get("DAY").toString(); String hour = job.get("HOUR").toString(); String minute = job.get("MINUTE").toString(); String second = job.get("SECOND").toString(); if (day == flag) { day = replaceFlag; } //替換星期字符域 //如果星期字符域有數據,日期字符域替換為replaceFlag"?" if (!(day==flag||day==replaceFlag)) { date = replaceFlag; } cronExpression = second + " " + minute + " " + hour + " " + date + " " + month + " " + day + " " + year; return cronExpression; } public static void shutdownQuartzJob(){ try { if(!sched.isShutdown()){ sched.shutdown(); } } catch (SchedulerException e) { e.printStackTrace(); logger.error("關閉QuartzJob異常"); } } }

4.編寫一個監聽器,並在Web.xml文件中配置監聽器

public class SystemInitListener implements ServletContextListener {

    private final static Logger logger = Logger.getLogger(SpringInitWeb.class);
    private MyBatisSessionTemplate jdbcTemplate; 
    private boolean success = true;
    private String retMessage;
    private ApplicationContext applicationContext = null;
    /* (non-Javadoc)
     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
     */
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        if (logger.isDebugEnabled()) {
            logger.debug(new StringBuilder().append("---------- Start to Destroy ServletContextListener  at ")
                    .append(System.currentTimeMillis()).append(" --------------").toString());
        }
        //關閉Quartz
        logger.info("開始關閉Quartz");
        QuartzJobConfig.shutdownQuartzJob();
        logger.info("Quartz已關閉");    

    }

    /* (non-Javadoc)
     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
     */
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        if (logger.isDebugEnabled()) {
            logger.debug(new StringBuilder().append("---------- Start to init ServletContextListener  at ")
                    .append(System.currentTimeMillis()).append(" --------------").toString());
        }
        systemStartup(arg0.getServletContext());

    }
    
    /**
     * 初始化全局變量
     */
    private void systemStartup(ServletContext servletContext) {
        if (logger.isDebugEnabled()) {
            logger.debug(new StringBuilder().append("---------- Start to 初始化全局變量  at ")
                    .append(System.currentTimeMillis()).append(" --------------").toString());
        }
        
        try {
            applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
            this.jdbcTemplate = (MyBatisSessionTemplate)SpringContextUtils.getBean("myBatisSessionTemplate");
        } catch (Exception e) {
            success = false;
            logger.error(e.getMessage(),e);
        }
        
        if (success) {
            BaseSupport.CframeUtil.InitDict(servletContext);
            BaseSupport.CframeUtil.InitSysParams(servletContext);
            logger.info("開始注冊定時任務");
            try{
                QuartzJobConfig.registerQuartzJob();
            }catch (Exception e){
                logger.info("定時任務注冊失敗");
            }
        }
    }

  <listener>
        <listener-class>com.cf.cfquartz.listener.SystemInitListener</listener-class>
    </listener>

 

5.編寫注冊registerQuartzJob的方法

 

public class QuartzJobBusiness implements Job {
    
    //資金賬號充值(帶輔助信息)屬性字段:start----------
    private String channelCode="201510310ROADOORP2P888888";    
    
    String msg_id=BaseSupport.CommonUtil.getUUID();
    String cust_code="2015121513248272640496338";
    String acc_no ="20151215122140132482726402096770";
    String card_code ="6217002870012789549";
    
    private String msg ="{\"head\":{\"msg_id\":\""+msg_id+"\",\"channel_code\":\"201510310ROADOORP2P888888\",\"service_code\":\"PAY_TOPUP_AUX_REQ\",\"version\":\"1\",\"callback_url\":\"http://172.16.200.11:8080/PService/testServiceAction!testService\"},\"body\":{\"cust_code\":\""+cust_code+"\",\"acc_no\":\""+acc_no+"\",\"card_code\":\""+card_code+"\",\"amount\":100,\"fee_pay_type\":\"0\",\"memo\":\"testmemo\",\"biz_code\":\"00000000SYS0000240004\" ,\"ori_seqno\":\"ORI_SEQNO_TEST\"}}";
    //資金賬號充值(帶輔助信息)屬性字段:end----------
    
    
    private final static Logger logger = Logger.getLogger(QuartzJobBusiness.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        // 判斷一下本機ip是多少,只在測試服務器和開發服務器上運行quartzjob
        InetAddress ia = null;
        String localname = null;
        String localip = null;
        try {
            ia = ia.getLocalHost();
            localname = ia.getHostName();
            localip = ia.getHostAddress();
            logger.info("本機名稱是:" + localname);
            logger.info("本機的ip是 :" + localip);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            logger.error(e.getMessage(),e);
        }
       
        // TB_JOB表ID作為Trigger的key名稱
        String jobId = context.getTrigger().getName();
        Map job = null;
        String errorMsg="";
        try{
            job = (Map) BaseSupport.myBatisSessionTemplate.selectOne("orm.mapper.TbJobMapper.selectJob", jobId);
        }catch(Exception e){
            logger.error("讀取數據庫失敗,失敗原因:"+ e.getMessage());
            errorMsg=e.getMessage();
        }
        if (null == job) {
            logger.info("沒有找到id為:" + jobId + "的任務");
        } else {
            if (!"1".equals(job.get("DEL"))) {
                logger.info("開始執行名為:" + job.get("JOB_NAME").toString() + "的任務");
                try {
                    executePServiceJob(job);
                    //int i=1/0;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    logger.debug(e.getMessage(),e);
                    errorMsg=e.getMessage();
                }
            }
        }
        Map<String,String> jobRunStatus=new HashMap<>();
        jobRunStatus.put("LOG_ID", BaseSupport.CommonUtil.getUUID());
        jobRunStatus.put("IP", localip);
        jobRunStatus.put("JOB_ID", jobId);
        jobRunStatus.put("RUN_TIME", BaseSupport.CframeUtil.GetCurrentLongTime());
        if("".equals(errorMsg)){
            jobRunStatus.put("IS_SUCCESS", JonConstant.SUCCESS_YES);
        }else{
            jobRunStatus.put("IS_SUCCESS", JonConstant.SUCCESS_NO);
            jobRunStatus.put("ERROR_MESSAGE", errorMsg);
        }
        BaseSupport.myBatisSessionTemplate.selectOne("orm.mapper.TbJobLog.insertJobLog", jobRunStatus);
    }

    private void executePServiceJob(Map job) throws Exception{
        String jobType = job.get("JOB_TYPE").toString();
        switch (jobType) {
     //此處就是數據表中的job編號
case ("01"): 。。。。case ("02"): 。。。。case ("03"): TransDailyReport transDailyReport = SpringContextUtils.getBean(TransDailyReport.class); transDailyReport.execute(); case ("04"):        。。。 break; } } }

 

 

6.編寫自己的業務方法,要實現的功能類。比如:TransDailyReport(excute方法)

 

public class TransDailyReport {
    private static final Logger logger = Logger.getLogger(TransDailyReport.class);
@Autowired
private MyBatisSessionTemplate myBatisSessionTemplate;
@Transactional(rollbackFor
=Exception.class) public void execute(){ 。。。。。 } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM