zoukankan      html  css  js  c++  java
  • spring结合quartz的定时的2种方式

    1、 Spring 的org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean类,使用此方法使开发人员对Quartz完全透明,需要实现定时任务的方法只是一个普通方法。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        <!-- 
        方法一:
        Spring 的org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean类,
        使用此方法使开发人员对Quartz完全透明,需要实现定时任务的方法只是一个普通方法。
         -->
        <!--1、 配置文件中添加业务类,该类为调用的工作类 -->
        <bean id="businessWork" class="com.morningstar.quartz.BusinessWork" />  
        
        <!-- 2、定义任务,在spring文件中配置代理类 ,定义调用对象和调用对象的方法--> 
        <bean id="businessTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
            <!-- 调用的类 -->        
            <property name="targetObject" ref="businessWork"/>
             <!-- 调用类中的方法 -->
            <property name="targetMethod" value="generateReport"/> 
            <!-- false,证明不执行并发任务 -->
            <property name="concurrent" value="false"/>      
        </bean> 
        <!-- 3、配置触发器,定义触发时间,可以根据不同的时间对同一个任务定义多个触发器,下面是每隔5秒调用一个方法配置-->
        <!-- cron表达式 -->
        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail" ref="businessTask"/>
            <property name="cronExpression" value="10,15,20,25,30,35,40,45,50,55 * * * * ?"/>
        </bean>
    
        <!-- 4、配置调度器 ,容器启动就会执行调度程序  -->
         <!-- 总管理类,如果lazy-init='false',则容器启动时就会执行调度程序-->  
         <!-- 如果lazy-init='true',则需要实例化该bean才能执行调度程序            -->  
        <bean id="schdulerFactory" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="cronTrigger"/>
                </list>
            </property>
        </bean>
    </beans>

    2、借助于Spring的org.springframework.scheduling.quartz.JobDetailBean的类功能, 继承 Spring封装Quartz的org.springframework.scheduling.quartz.QuartzJobBean类,实现 executeInternal方法,executeInternal方法中调用业务类。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        <!-- 
        方法二:
        借助于Spring的org.springframework.scheduling.quartz.JobDetailBean的类功能,
        继承 Spring封装Quartz的org.springframework.scheduling.quartz.QuartzJobBean类,实现 executeInternal方法,
        executeInternal方法中调用业务类
         -->
        <!-- 1、定义任务,在spring文件中配置代理类 ,定义调用对象和调用对象的方法--> 
        <bean id="businessTask" class="org.springframework.scheduling.quartz.JobDetailBean">  
            <!-- 调用的类 -->        
            <property name="jobClass" value="com.morningstar.quartz.BusinessWork"/>
            <!-- 主要是为了在定时任务需要使用到Bean,通过Spring给注入进来,如果不写明,就会报java.lang.NullPointerException错误 -->
            <!--  
            <property name="jobDataAsMap">
                <map>
                    <entry key="someService">
                        <ref bean="someService" />
                    </entry>
                  </map>
              </property>
              -->
        </bean> 
        
        <!-- 2、配置触发器,定义触发时间,可以根据不同的时间对同一个任务定义多个触发器-->
        <!-- cron表达式 -->
        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail" ref="businessTask"/>
            <property name="cronExpression" value="10,15,20,25,30,35,40,45,50,55 * * * * ?"/>
        </bean>
    
        <!-- 3、配置调度器 ,容器启动就会执行调度程序  -->
         <!-- 总管理类,如果lazy-init='false',则容器启动时就会执行调度程序-->  
         <!-- 如果lazy-init='true',则需要实例化该bean才能执行调度程序            -->  
        <bean id="schdulerFactory" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="cronTrigger"/>
                </list>
            </property>
        </bean>
    </beans>
    Quartz 是优秀的开源的任务调度框架,它提供了强大任务调度机制。Quartz允许开发人员定义触发器的调度时间表,并提供了触发器和任务之间的关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
    Spring为创建Quartz的Scheduler、Trigger和JobDetail提供了便利的FactoryBean类,以便能够在Spring 容器中享受注入的好处,主要有以下两个方面:
        1)为Quartz的重要组件类提供更具Bean风格的扩展类; 
        2)提供创建Scheduler的BeanFactory类,方便在Spring环境下创建对应的组件对象,并结合Spring容器生命周期进行启动和停止的动作。
    JobDetailBean
    关于JobDetail, Spring通过扩展JobDetail提供了一个JobDetailBean(org.springframework.scheduling.quartz包里)。JobDetailBean可以配置以下属性,其任务类如果实现了org.quartz.Job,则jobDataAsMap的值的修改无法保留到下一次执行,如果实现了org.quartz.StatefulJob:
    ● jobClass:类型为Class,实现Job/StatefulJob接口的任务类; 
        ● beanName:默认为Bean的id名,通过该属性显式指定Bean名称,它对应任务的名称;
     
        ● jobDataAsMap:类型为Map,为任务所对应的JobDataMap提供值。Spring通过jobDataAsMap设置JobDataMap的值;
     
        ● applicationContextJobDataKey:你可以将Spring ApplicationContext的引用保存到JobDataMap中,以便在Job的代码中访  问ApplicationContext。为了达到这个目的,你需要指定一个键,用以在jobDataAsMap中保存ApplicationContext,如果不设置此键,JobDetailBean就不将ApplicationContext放入到JobDataMap中。
     
        ● jobListenerNames:类型为String[],指定注册在Scheduler中的JobListeners名称,以便让这些监听器对本任务的事件进行监听。
    ***此外,Spring提供了一个MethodInvokingJobDetailFactoryBean,通过这个FactoryBean可以将Spring容器中Bean的方法包装成Quartz任务,这样开发者就不必为Job创建对应的类。否则该类只是简单包含调用Bean的方法,并无实际使用价值。这个FactoryBean的配置实例如下(假设封装businessBean的schedulerMethod方法,以有状态Job调度,即其中的JobDataMap将得到维持,concurrent默认为true,即无状态Job调度):
    <bean id="methodJobSmp" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="businessBean" />
        <property name="targetMethod" value="schedulerMethod" />
        <property name="concurrent" value="false" />
      </bean>
    注意:其中的schedulerMethod方法即可以是static,也可以是非static的,但不能拥有方法入参。通过MethodInvokingJobDetailFactoryBean产生的JobDetail不能被序列化,所以不能被持久化到数据库中的,如果希望使用持久化任务,则你只能创建正规的Quartz的Job实现类了。
    有了JobDetail作为具体任务,我们还需要Spring帮我们调度到调度器里去生效。Spring可以配置三种调度,其中简单调度SimpleTriggerBean,定时调度CronTriggerBean是为Quartz扩展(org.springframework.scheduling.quartz包里),还自己提供了计时调度ScheduledTimerTask(org.springframework.scheduling.timer里)。
    SimpleTriggerBean配置实例如下(任务为jobDetailBeanName,是一个JobDetailBean的id,可是是具体实现类,也可以是MethodInvokingJobDetailFactoryBean配置的代理类;延迟10秒后启动,时间间隔为20秒,重复执行100次,配置任务变量count值为10):
    <bean id="simpleTrigger1" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="jobDetailBeanName" />
    <property name="startDelay" value="1000" />
    <property name="repeatInterval" value="2000" />
    <property name="repeatCount" value="100" />
    <property name="jobDataAsMap">
    <map>
    <entry key="count" value="10" />
    </map>
    </property>
    </bean>
     
    CronTriggerBean配置实例如下(任务为jobDetailBeanName,调度时间表是每天每隔三小时运行(0点,3点,6点,…)
    <bean id="cronTriggerSmp" class="org.springframework.scheduling.quartz.CronTriggerBean">
             <property name="jobDetail" ref="jobDetailBeanName"/>
             <property name="cronExpression" value="0 0 */3 * * ? *"/>
      </bean>
    cronExpression的表示式规范:
    域名
    强制?
    允许值范围
    支持的特殊字符
    0-59
    - * /
    0-59
    - * /
    0-23
    - * /
    1-31
    - * / ? L W C
    1-12
    - * /
    星期
    1-7(SUN-SAT)
    - * / ? L C #
    非空
    1970-2099
    - * /
     
    计时调度ScheduledTimerTask配置实例如下(任务为jobDetailBeanName,执行间歇间隔为60秒,执行间隔为3600000毫秒)
    <bean id="timerTaskExample" class="org.springframework.scheduling.timer.ScheduledTimerTask">
        <property name="delay" value="60"/>
        <property name="period" value="3600000"/>
        <property name="timerTask" ref="jobDetailBeanName"/>
      </bean>
     
    有了调度项,我们可以把他们简单添加到调度器里去即可。Spring为计时调度ScheduledTimerTask提供了调度器工厂BEAN--TimerFactoryBean(org.springframework.scheduling.timer包里),该调度器配置实例如下:
    <bean id="timeSample" class="org.springframework.scheduling.timer.TimerFactoryBean">
        <property name="scheduledTimerTasks">
          <list>
            <ref bean=" timerTaskExample "/><!—可以很多 -->
          </list>
        </property>
      </bean>
     
    Sprint还为扩展Quartz的调度CronTriggerBean、SimpleTriggerBean也扩展了调度器工厂BEAN—SchedulerFactoryBean(org.springframework.scheduling.quartz包里),其配置实例如下:
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
         <property name="autoStartup"><!-初始化后是否马上启动Scheduler,默认是true. -->
                <value>true</value>
            </property>
    <property name="startupDelay"><!-初始化后是否延时多少秒启动Scheduler,默认是0马上启动,通过startupDelay属性让Scheduler延迟一小段时间后启动,以便让Spring能够更快初始化容器中剩余的Bean. -->
                <value>0</value>
            </property>
             <property name="triggers">
                    <list>
                           <ref local="simpleTrigger1"/>             
                           <ref local="cronTriggerSmp "/>          
                           <ref local="quartzTrigger1"/>             
                    </list>
             </property>
    <property name="schedulerContextAsMap"> <!—context setting -->
        <map>
            <entry key="keya" value="valuea"/>
        </map>
    </property>
    <property name="configLocation" value="classpath:com/coma/projb/quartz/quartz.properties" />
      </bean>
      还有calendars属性(类型为Map,通过该属性向Scheduler注册Calendar),jobDetails属性(类型为JobDetail[],通过该属性向Scheduler注册JobDetail)用得不多。
    SchedulerFactoryBean还可以通过以下属性代替框架的自身配置文件: 
        ● dataSource:当需要使用数据库来持久化任务调度数据时,你可以在Quartz中配置数据源,也可以直接在Spring中通过dataSource指定一个Spring管理的数据源。如果指定了该属性,即使quartz.properties中已经定义了数据源,也会被此dataSource覆盖;
     
        ● transactionManager:可以通过该属性设置一个Spring事务管理器。在设置dataSource时,Spring强烈推荐你使用一个事务管理器,否则数据表锁定可能不能正常工作;
     
        ● nonTransactionalDataSource:在全局事务的情况下,如果你不希望Scheduler执行化数据操作参与到全局事务中,则可以通过该属性指定数据源。在Spring本地事务的情况下,使用dataSource属性就足够了;
     
        ● quartzProperties:类型为Properties,允许你在Spring中定义Quartz的属性。其值将覆盖quartz.properties配置文件中的设置,这些属性必须是Quartz能够识别的合法属性,配置quartzProperties属性实例如下:
    bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="quartzProperties">
    <props>
    <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
    <prop key="org.quartz.threadPool.threadCount">10</prop>
    </props>
    </property>
    </bean>
  • 相关阅读:
    系统维护相关问题
    Python环境维护
    哈希表解决字符串问题
    论文笔记二:《A Tutoral on Spectral Clustering》
    论文笔记之哈希学习比较--《Supervised Hashing with Kernels》《Towards Optimal Binary Code Learning via Ordinal Embedding》《Top Rank Supervised Binary Coding for Visual Search》
    Java中String、StringBuffer、StringBuilder的比较与源 代码分析
    浙大pat1040 Longest Symmetric String(25 分)
    浙大pat1039 Course List for Student(25 分)
    浙大pat---1036 Boys vs Girls (25)
    百炼oj-4151:电影节
  • 原文地址:https://www.cnblogs.com/tomcattd/p/3512811.html
Copyright © 2011-2022 走看看