zoukankan      html  css  js  c++  java
  • quartz使用(整合spring)

    quartz与spring整合后,还是需要Scheduler实例、JobDetail实例、Trigger实例,只不过是用FactoryBean的方式创建了。

    在spring-context-support-xxx.jar包中有对应的FactoryBean类,Scheduler实例对应org.springframework.scheduling.quartz.SchedulerFactoryBeanJobDetail实例对应两个FactoryBean类,org.springframework.scheduling.quartz.JobDetailFactoryBean和org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBeanTrigger实例对应两个FactoryBean类,org.springframework.scheduling.quartz.SimpleTriggerFactoryBean和org.springframework.scheduling.quartz.CronTriggerFactoryBean,SimpleTriggerFactoryBean对应生成SimpleTrigger实例,CronTriggerFactoryBean对应生成CronTrigger实例。

    用MethodInvokingJobDetailFactoryBean创建的JobDetail实例不能序列化,不适于任务调度信息持久化的情况,所以说如果要持久化任务调度信息的话,只能用JobDetailFactoryBean来创建JobDetail实例。

    这几项对应的spring配置文件内容如下:

        <bean id="printJobDetail"
              class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
            <property name="jobClass" value="com.kou.quartz.QuartzPrint"/>
            <property name="durability" value="false"/>
        </bean>
    
        <bean id="printCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="jobDetail" ref="printJobDetail"/>
            <property name="cronExpression" value="0/5 * * * * ? *"/> <!-- 每5秒触发一次 -->
        </bean>
    
        <bean id="springBeanJobFactory" class="org.springframework.scheduling.quartz.SpringBeanJobFactory"/>
    
        <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <!-- 指定quartz配置文件-->
            <property name="configLocation" value="classpath:quartz.properties"/>
            <!--QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动,单位秒 -->
            <property name="startupDelay" value="30"/>
            <!-- 设置自动启动 -->
            <property name="autoStartup" value="true"/>
            <property name="triggers">
                <list>
                    <ref bean="printCronTrigger"/>
                </list>
            </property>
            <property name="overwriteExistingJobs" value="true"/>
            <!--<property name="dataSource" ref="dataSource"/>-->
            <property name="jobFactory" ref="springBeanJobFactory"/>
        </bean>

    JobDetailFactoryBean的jobClass属性值就是我们自己开发的任务类,需要实现org.quartz.Job接口或者继承QuartzJobBean(全类名是org.springframework.scheduling.quartz.QuartzJobBean,也在spring-context-support-xxx.jar包),我们在execute()或executeInternal()方法中写自己的业务代码即可。

    SchedulerFactoryBean的configLocation属性值就是上一篇《quartz入门》中介绍的quartz.properties配置文件,放在classpath下。

    SchedulerFactoryBean的overwriteExistingJobs属性默认为false,当trigger由每5秒执行一次变为每30秒执行一次时,任务调度是不会更改的,只有设为true之后才会更改。

    如果quartz.properties文件中有配置数据库信息的话(org.quartz.dataSource开头的一些配置),则SchedulerFactoryBean的dataSource属性可以不设置,否则要设置。

    以上,定时任务就可以跑起来了。但是如果想在自定义的job中引用spring bean的话,会发现引不进来。还需要进行一些额外的操作:给scheduler设置jobFactory。如果我们不设的话,默认是AdaptableJobFactory实例。AdaptableJobFactory全类名是org.springframework.scheduling.quartz.AdaptableJobFactory。如果想在任务中引用spring的bean,我们可以利用其子类SpringBeanJobFactory,全类名是org.springframework.scheduling.quartz.SpringBeanJobFactory,这个类重写了父类的createJobInstance()方法。

    如果不想用spring的配置文件,则也可以把这些配置信息转成代码:

    @Configuration
    public class Config {
    
        private static final Kconf<String> PRINT_JOB_CRON = Kconfs.ofString("young.admin.printJobCron", "0/30 * * * * ? *")
                .build();
    
        private static final Kconf<String> MMU_UPDATE_AUDIT_STATUS_JOB_CORN = Kconfs.ofString("young.admin.mmuUpdateAuditStatusJobCron", "0 0 2 * * ? *")
                        .build();
    
        @Bean("printJobDetail")
        public JobDetailFactoryBean getPrintJobDetail() {
            JobDetailFactoryBean bean = new JobDetailFactoryBean();
            bean.setJobClass(QuartzPrint.class);
            bean.setDurability(true);
            return bean;
        }
    
        @Bean("printCronTrigger")
        public CronTriggerFactoryBean getPrintCronTrigger(JobDetail printJobDetail) {
            CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
            bean.setCronExpression(PRINT_JOB_CRON.get());
            bean.setJobDetail(printJobDetail);
            return bean;
        }
    
        @Bean("mmuUpdateAuditStatusJobDetail")
        public JobDetailFactoryBean getMmuUpdateAuditStatusJobDetail() {
            JobDetailFactoryBean bean = new JobDetailFactoryBean();
            bean.setJobClass(MmuUpdateAuditStatusJob.class);
            bean.setDurability(true);
            return bean;
        }
    
        @Bean("mmuUpdateAuditStatusCronTrigger")
        public CronTriggerFactoryBean getMmuUpdateAuditStatusCronTrigger(JobDetail mmuUpdateAuditStatusJobDetail) {
            CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
            bean.setCronExpression(MMU_UPDATE_AUDIT_STATUS_JOB_CORN.get());
            bean.setJobDetail(mmuUpdateAuditStatusJobDetail);
            return bean;
        }
    
        @Bean(name = "scheduler")
        public SchedulerFactoryBean getScheduler(Trigger printCronTrigger, Trigger mmuUpdateAuditStatusCronTrigger) {
            SchedulerFactoryBean bean = new SchedulerFactoryBean();
            // 延时启动,应用启动10秒后
            bean.setStartupDelay(10);
            bean.setOverwriteExistingJobs(true);
            bean.setConfigLocation(new ClassPathResource("quartz.properties"));
            bean.setTriggers(printCronTrigger, mmuUpdateAuditStatusCronTrigger);
            bean.setJobFactory(new SpringBeanJobFactory());
            return bean;
        }
    
    }

    代码中的QuartzPrint、MmuUpdateAuditStatusJob都是集成QuartzJobBean的自定义类。

    注意,trigger的cron表达式不要写死,要从配置文件或者从配置中心读取,这样,想更改调度规则的话,就不用改代码了,直接改配置项,然后重启服务器就好了。

  • 相关阅读:
    Android ViewPager实现选项卡切换
    Android Fragment是什么
    Android 点击文字实现跳转
    海底捞的十五天,让我重当程序员
    saltstack 实现haproxy+keepalived
    saltstack 实现系统初始化
    saltstack 实现redis主从
    python类基础
    Mysql 数据库备份工具 xtrabackup
    Python函数式编程
  • 原文地址:https://www.cnblogs.com/koushr/p/5873467.html
Copyright © 2011-2022 走看看