quartz 可配置的定时服务
来源:互联网 发布:windows 网络访问权限 编辑:程序博客网 时间:2024/06/11 06:25
一、可配置的定时服务先设计数据库表结构
CREATE TABLE `job` (`id` CHAR(36) NOT NULL,`name` VARCHAR(36) NOT NULL COMMENT '任务名',`bean_name` VARCHAR(100) NOT NULL COMMENT 'spring bean name',`execute_exp` VARCHAR(200) NOT NULL COMMENT '执行的表达式',`state` INT(11) NOT NULL DEFAULT '1' COMMENT '1有效2无效',`remark` VARCHAR(100) NULL DEFAULT '1' COMMENT '描述信息',`create_time` DATETIME NOT NULL,PRIMARY KEY (`id`))二、定义QuartzManager 管理器 可以使得注入可用
public class QuartzManager { private static SchedulerFactory sf = null; private static String Default_JOB_GROUP_NAME = "job_group"; private static String Default_TRIGGER_GROUP_NAME = "job_trigger"; static { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader == null) { classLoader = QuartzManager.class.getClassLoader(); } // 加载属性文件app.properties InputStream is = null; try { is = classLoader.getResourceAsStream("conf/quartz.properties"); Properties properties = new Properties(); properties.load(is); is.close(); is = null; sf = new StdSchedulerFactory(properties); } catch (Exception e1) { e1.printStackTrace(); } } /** * 添加任务 * * @param jobName * @param triggerName * @param jobClass * @param time * @return * @throws SchedulerException * @throws ParseException */ public static JobDetail addJob(String jobId, String triggerName, String beanName, Class<? extends Job> jobClass, String time) throws SchedulerException, ParseException { Scheduler sched = sf.getScheduler(); JobDetail jobDetail = newJob(jobClass).withIdentity(jobId, Default_JOB_GROUP_NAME).build();// 任务名,任务组,任务执行类 jobDetail.getJobDataMap().put("beanName", beanName); jobDetail.getJobDataMap().put("jobId", jobId); CronTrigger trigger = newTrigger().withIdentity(triggerName, Default_TRIGGER_GROUP_NAME) .withSchedule(cronSchedule(time)).build(); sched.scheduleJob(jobDetail, trigger); if (!sched.isShutdown()) sched.start(); return jobDetail; } public static List<? extends Trigger> getTriggerKeys(JobKey jobKey) throws SchedulerException { return sf.getScheduler().getTriggersOfJob(jobKey); } /** * 触发一个任务 * * @param jobKey * @throws SchedulerException */ public static void triggerJob(JobKey jobKey) throws SchedulerException { sf.getScheduler().triggerJob(jobKey); } /** * 得到一个触发器的任务状态 * * @param triggerKey * @return * @throws SchedulerException */ public static TriggerState getTriggerState(TriggerKey triggerKey) throws SchedulerException { return sf.getScheduler().getTriggerState(triggerKey); } /** * 移除任务 * * @param jobName * @param triggerName * @param jobClass * @param time * @return * @throws SchedulerException * @throws ParseException */ public static void removeJob(JobKey jobKey) throws SchedulerException { Scheduler sched = sf.getScheduler(); sched.pauseJob(jobKey); sched.deleteJob(jobKey); } public static void clearAll() throws SchedulerException { Scheduler sched = sf.getScheduler(); sched.clear(); sched.shutdown(); }}三、定义接口类
public interface IQuartzBaseJobService { public boolean execute(Job job);}四、每个新的beanName 实现 IQuartzBaseJobService走自己的逻辑
五、考虑到每个接口只实现,自己的业务不能加日志等信息,需要定义一个类来完成这事
public class QuartzSpringBeanJob implements org.quartz.Job { private final Logger logger = LoggerFactory.getLogger(QuartzSpringBeanJob.class); @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail job = context.getJobDetail(); String jobId = job.getJobDataMap().getString("jobId"); String jobBeanName = job.getJobDataMap().getString("beanName"); if (StringUtils.isEmpty(jobId) || StringUtils.isEmpty(jobBeanName)) { return; } boolean success = true; String message = ""; // 检查当前job是否可以执行 IJobService jobService = SpringContextHolder.getBean("jobService"); Job jobBean = jobService.findUnique(jobId); if (jobBean == null || jobBean.getState() != BooleanEnum.True.getValue()) { try { QuartzManager.removeJob(job.getKey()); } catch (SchedulerException e) { logger.error(e.getMessage(), e); e.printStackTrace(); } return; } IJobLogService jobLogService = SpringContextHolder.getBean("jobLogService"); // 查询上一次是否已经执行成功 boolean existsDoing = jobLogService.existsUnComplete(jobId); // 生成job日志 JobLog jobLog = new JobLog(); jobLog.setId(GuidKeyGenerator.getUUIDKey()); jobLog.setJobId(jobId); jobLog.setStartTime(new Date()); if(!existsDoing){ jobLog.setState(JobLogStateEnum.Doing.getValue()); } else { jobLog.setState(JobLogStateEnum.UnStart.getValue()); jobLog.setMessage("上次未执行结束!本次不再执行!"); } jobLogService.create(jobLog); if(existsDoing){// 还有没有执行完的,就不再执行了 return ; } try { IQuartzBaseJobService quartzBaseJobService = SpringContextHolder.getBean(jobBeanName);//为自己bean if (quartzBaseJobService != null) { quartzBaseJobService.execute(jobBean); } } catch (Exception e) { success = false; message = e.getMessage(); logger.error(e.getMessage(), e); } // 更新日志状态 JobLog newJobLog = new JobLog(); newJobLog.setId(jobLog.getId()); newJobLog.setState(success ? JobLogStateEnum.Success.getValue() : JobLogStateEnum.Error.getValue()); newJobLog.setEndTime(new Date()); newJobLog.setMessage(message); jobLogService.update(newJobLog, jobLog); }六、一般spring 启动就想执行监听
@Servicepublic class JobTaskService implements IJobTaskService, Initalizer { private final Logger logger = LoggerFactory.getLogger(JobTaskService.class); private final static Map<String, JobDetail> jobDetailMap = new HashMap<String, JobDetail>(); @Autowired private IJobService jobService; @Autowired private IJobLogService jobLogService; @Override public void initalize() { jobLogService.clearDoing(); startAll(); } private void startAll() { List<Job> jobs = jobService.findValid(); if (jobs == null) return; for (Job job : jobs) { try { JobDetail jobDetail = QuartzManager.addJob(job.getId(), "trigger-" + job.getId(), job.getBeanName(), QuartzSpringBeanJob.class, job.getExecuteExp()); jobDetailMap.put(job.getId(), jobDetail); } catch (Exception e) { e.printStackTrace(); logger.error("addJobError:jobId:" + job.getId() + e.getMessage(), e); } } }}七、考虑到新增修改删除,所以我把我用的方法列
public static void removeJob(String jobName) throws SchedulerException{ try { Scheduler sched = sf.getScheduler(); sched.pauseTrigger(new TriggerKey(jobName, Default_TRIGGER_GROUP_NAME));// 停止触发器 sched.unscheduleJob(new TriggerKey(jobName, Default_TRIGGER_GROUP_NAME));// 移除触发器 sched.deleteJob(new JobKey(jobName, Default_JOB_GROUP_NAME));// 删除任务 } catch (Exception e) { throw new RuntimeException(e); } } public static void modifyJobTime(String triggerName, String triggerGroupName, String time) { try { Scheduler sched = sf.getScheduler(); TriggerKey triggerKey = new TriggerKey(triggerName,Default_TRIGGER_GROUP_NAME);CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey); CronScheduleBuilder scheduleBuilder = cronSchedule(time); if (trigger == null) { return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(time)) { trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build(); //按新的trigger重新设置job执行 sched.rescheduleJob(triggerKey, trigger); } } catch (Exception e) { throw new RuntimeException(e); } } public static void clearAll() throws SchedulerException { Scheduler sched = sf.getScheduler(); sched.clear(); sched.shutdown(); } <pre name="code" class="java"> /** * 触发一个任务 * * @param jobKey * @throws SchedulerException */ public static void triggerJob(JobKey jobKey) throws SchedulerException { sf.getScheduler().triggerJob(jobKey); }
八、总结一下
Trigger 就是个触发器 jobDetail 就是那个类要作这件事情
scheduler 一个工厂对象返回,作什么事几点作就可以了。
scheduler.start();
成了
1 0
- quartz 可配置的定时服务
- Spring 配置Quartz 定时任务调度服务
- 使用quartz+spring实现简单的可配置化的定时任务(可和数据库配套使用)
- 调度服务Quartz的配置
- spring集成quartz定时任务的配置
- Quartz两个定时任务的配置
- 定时任务-quartz的使用,实现可页面化管理
- 定时任务-quartz的使用,实现可页面化管理
- quartz定时配置
- Quartz定时任务配置
- Quartz定时任务配置
- Quartz定时 配置
- Quartz定时任务配置
- spring 定时服务调度quartz
- 有关 定时服务Timer, spring良好的支持了quartz
- 定时任务-quartz的使用,实现可页面化管理 标签: quartz
- quartz 定时编辑器(反编译亦可)
- spring的quartz定时
- python finally使用
- 棋牌游戏开发之斗地主算法点选牌
- Apache服务器关闭TRACE Method请求方式
- Android Retrofit使用详解
- 使用tapestry-prop提高Tapestry运行效率
- quartz 可配置的定时服务
- 通过List集合向前台显示文件类型
- nyoj 水仙花数
- Java之String.format
- linux内核源码总览之0000--------备分,未整理,虚拟文件系统1
- Tapestry4改进运行效率的实现方法
- OC第二天
- 棋牌游戏开发之地主AI算法实现
- activity跳转闪现黑屏