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