quartz定时任务之自定义注解实现动态配置任务
来源:互联网 发布:魔戒巫师知乎 编辑:程序博客网 时间:2024/05/30 19:35
项目需求:定时任务
实现方式?
spring自带定时任务,jdk自带Timer,quartz实现。
优缺点,spring,基于注解实现,配置简单,但是后期任务丰富,之后,修改配置较为困难,且不容易控制
jdk自带,实现简单,不便于控制,
quartz,功能强大,可配置。
所以为了以后项目的扩展,果断采用quartz,引入quartz jar包,
quartz-2.2.3.jar quartz-jobs-2.2.3.jar
spring 4.0
quartz实现任务配置
编写执行代码:
@Componentpublic class TestJob { public void exe(){ System.out.println("hello test"); }}
<!--定义jobdetail--><bean id="testTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="testJob "/> <property name="targetMethod" value="exe"/> </bean> <!--定义触发器--> <bean id="handletrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="testTask"/> <property name="cronExpression" value="${handle_cron}"/> </bean> 以上操作,每次 <!--定义调度器--><bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="testtrigger"/> <ref bean="testtrigger1"/> <ref bean="testtrigger2"/> </list> </property> <property name="autoStartup" value="true"/> </bean>
每次新增一个调度任务,都需要在xml里添加这些配置,真心麻烦
减少配置
1.分析
为了减少xml的配置,我们可以观察一下,spring项目中,启动一个任务的配置顺序,不难发现,
org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean和org.springframework.scheduling.quartz.CronTriggerFactoryBean
是实例化一个任务对象的java对象,都是spring对quartz的封装,
其次是org.springframework.scheduling.quartz.SchedulerFactoryBean
调度器,实现对上一步任务对象的调度
所以我们要减少配置,就要从SchedulerFactoryBean入手,重写SchedulerFactoryBean,使他能够自动注册任务对象,这其中用到了自定义注解
2.代码实现
自定义注解
import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Job { //定时任务分组 String group() default "default"; //执行任务方法 String executeMethod() default "execute"; //执行任务表达式,可支持${}表达式,默认从config/job.properties加载配置cron表达式 String cron() default "";}
重写的任务调度器SchedulerFactoryBean,实现自动装配任务
import java.util.ArrayList;import java.util.Collection;import java.util.List;import java.util.Map;import java.util.Properties;import org.quartz.JobKey;import org.quartz.Trigger;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import org.springframework.stereotype.Component;/** * * @author ll * 动态配置任务添加 *后期可以从数据库中配置任务,提供接口停止,重新安排,暂停任务等接口 */@Componentpublic class EcrDynamicScheduler extends SchedulerFactoryBean implements ApplicationContextAware { private static ApplicationContext applicationContext; //默认配置文件地址 private static final String DEFAULT_CONFIG_PATH="config/job.properties"; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext=applicationContext; init(); } private void init(){ //获取自定义注解bean对象 Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(Job.class); if(beansWithAnnotation!=null){ try { Collection<Object> values = beansWithAnnotation.values(); MethodInvokingJobDetailFactoryBean jobBean=null; CronTriggerFactoryBean triggerBean=null; List<Trigger> triggerBeans=new ArrayList<Trigger>(); //读取默认cron表达式配置文件 Properties properties=PropertiesUtils.getProperties(DEFAULT_CONFIG_PATH); for(Object targetObject:values){ //创建jobbean jobBean=new MethodInvokingJobDetailFactoryBean(); //获取bean上的注解 Job jobAnno = targetObject.getClass().getAnnotation(Job.class); //获取注解内容 String group = jobAnno.group(); String executeMethod = jobAnno.executeMethod(); String beanName=targetObject.getClass().getSimpleName(); String cron=jobAnno.cron(); if(cron.contains("${")){//如果cron是el表达式,则从配置文件中获取 cron=properties.getProperty(cron.substring(2, cron.indexOf("}")), ""); } jobBean.setTargetObject(targetObject); jobBean.setGroup(group); jobBean.setTargetMethod(executeMethod); jobBean.setBeanName(beanName+"_jobBean"); //jobkey:group.beanName.executeMethod jobBean.setName(beanName+"."+executeMethod); jobBean.afterPropertiesSet(); //创建触发器 triggerBean=new CronTriggerFactoryBean(); triggerBean.setJobDetail(jobBean.getObject()); triggerBean.setCronExpression(cron); triggerBean.setBeanName(beanName+"_triggerBean"); triggerBean.setName(beanName+"."+executeMethod); triggerBean.afterPropertiesSet(); triggerBeans.add(triggerBean.getObject()); } Trigger[] triggers = triggerBeans.toArray(new Trigger[triggerBeans.size()]); //交给执行器执行 setAutoStartup(true); setTriggers(triggers); } catch (Exception e) { e.printStackTrace(); } } }}
这个重写的SchedulerFactoryBean比较简单,也是因为项目需求也比较简单,所以就没有写太多功能,其实还有很多可以扩充的地方,可以保存任务对象jobkey和jobdetail,
实现任务对象的暂停,删除,重新安排等操作
- quartz定时任务之自定义注解实现动态配置任务
- Quartz实现数据库动态配置定时任务
- quartz 配置 动态定时任务
- Quartz实现动态定时任务
- quartz实现动态定时任务
- Quartz实现动态定时任务
- Quartz实现动态定时任务
- springboot整合Quartz实现动态配置定时任务
- quartz工具类实现动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- quartz动态定时任务
- Spring Quartz 动态配置定时任务
- Spring Quartz 动态配置定时任务
- Spring Quartz 动态配置定时任务
- 使用Quartz配置动态定时任务(总结)
- Spring+Quartz实现动态添加定时任务
- Spring+Quartz实现动态添加定时任务
- HDU6168-Numbers(离散|哈希)
- Flask实战2问答平台--导航条
- 封装成一个微信接口类
- HDU 6154 CaoHaha's staff
- 利用 caffe 接口构建 CNN 网络
- quartz定时任务之自定义注解实现动态配置任务
- 2017中国软件成本度量大会亮点提前看!
- 关于在git新建分支后IntelliJ IDEA不会自动刷新分支问题解决
- 小心情:继续未来的路
- idea maven多环境配置文件
- 发布的QT程序无法显示图标和图片的问题
- bootloader详解
- 47种常见的浏览器兼容性问题大汇总
- 基于 VCamera,仿微信录制短视频