quartz定时任务之自定义注解实现动态配置任务

项目需求:定时任务

实现方式?

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,
实现任务对象的暂停,删除,重新安排等操作

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个快速开发的框架,可以方便地快速构建Spring应用程序。Quartz是一个开源的定时任务调度框架,可以让开发者方便地实现任务的定时提醒。在Spring Boot中使用Quartz可以实现任务定时提醒功能。 1. 导入Quartz依赖 首先需要在pom.xml文件中导入Quartz依赖: ``` <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> ``` 2. 创建Job任务Spring Boot中可以通过实现Job接口来创建任务,以下是一个简单的任务: ``` @Component public class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("任务执行中..."); } } ``` 3. 配置定时任务Spring Boot中可以通过配置类来配置定时任务,以下是一个简单的配置: ``` @Configuration public class QuartzConfig { @Autowired private MyJob myJob; @Bean public JobDetail myJobDetail() { return JobBuilder.newJob() .ofType(MyJob.class) .storeDurably() .withIdentity("MyJob") .withDescription("执行MyJob任务") .build(); } @Bean public Trigger myJobTrigger() { SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(5) .repeatForever(); return TriggerBuilder.newTrigger() .forJob(myJobDetail()) .withIdentity("MyJobTrigger") .withDescription("每隔5秒执行一次") .withSchedule(scheduleBuilder) .build(); } } ``` 配置类中定义了一个自定义任务(myJob),并通过@Bean注解将任务绑定到JobDetail和Trigger中,TaskScheduler将会按照我们定义的时间间隔和任务执行次数,周期性地执行MyJob中所定义的任务内容。 4. 启动任务 最后需要在应用程序中启动任务,在应用启动时自动启动任务: ``` @SpringBootApplication public class DemoApplication { @Autowired private Scheduler scheduler; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @PostConstruct public void start() throws SchedulerException { scheduler.scheduleJob(myJobDetail(), myJobTrigger()); scheduler.start(); } } ``` @PostConstruct注解表示在初始化Bean之后自动执行。在这个方法中启动任务,即注册JobDetail和Trigger,并启动任务调度器,以便Job被调度执行。现在每隔5秒就会执行一次任务了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值