quartz定时任务之自定义注解实现动态配置任务
2017-08-23 14:36
381 查看
项目需求:定时任务
实现方式?
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实现任务配置
编写执行代码:@Component public 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) @Documented public @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 * 动态配置任务添加 *后期可以从数据库中配置任务,提供接口停止,重新安排,暂停任务等接口 */ @Component public 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,
实现任务对象的暂停,删除,重新安排等操作
相关文章推荐
- spring boot 集成quartz 2.0 实现前端动态配置(获取spring上下文)的两种方式,启动数据库中已开启定时任务
- springboot整合Quartz实现动态配置定时任务
- Quartz实现数据库动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】
- springboot整合Quartz实现动态配置定时任务的方法
- springboot整合Quartz实现动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- quartz工具类实现动态配置定时任务
- Quartz实现JAVA定时任务的动态配置的方法
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- [置顶] spring整合quartz实现动态定时任务的前台网页配置与管理
- Springboot整合Quartz实现动态配置定时任务
- spring boot 集成quartz 2.0 实现前端动态配置(获取spring上下文)的两种方式,启动数据库中已开启定时任务
- Quartz实现数据库动态配置定时任务
- Quartz实现JAVA定时任务的动态配置
- springboot整合Quartz实现动态配置定时任务
- springboot整合Quartz实现动态配置定时任务
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码