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(){ 。。。。。 } }