spring配置 quartz-config.xml


    <!-- 配置調度程序quartz ,其中配置JobDetail有兩種方式-->
    <!-- 使用MethodInvokingJobDetailFactoryBean,任務類可以不實現Job接口,通過targetMethod指定調用方法-->
    <!-- 定義目標bean和bean中的方法 -->
    <bean id="SpringQtzJob" class="com.sky.JobSchedule.Job.JobTest"/>
    <bean id="SpringQtzJobMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="SpringQtzJob"/>
        </property>
        <property name="targetMethod">  <!-- 要執行的方法名稱 -->
            <value>helloSky</value>
        </property>
        <property name="arguments" value="11"/>
        <property name="concurrent " value="false"></property >     <!--非並發-->
    </bean>

    <!--  調度觸發器  -->
    <bean id="CronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="SpringQtzJobMethod"></property>
        <property name="cronExpression" value="0/5 * * * * ?"></property>
    </bean>

    <!--  調度工廠  -->
    <bean id="SpringJobSchedulerFactoryBean" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="CronTriggerBean"/>
            </list>
        </property>
    </bean>

  

public class JobTest {
    String name;

    public JobTest() {
        System.out.println("Hello, Quartz! ----------------------");
    }

    public void helloSky(int age) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println("Hello, " + age + " sky !" + formatter.format(new Date()));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

  

    public static void main(String[] args) throws SchedulerException {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:quartz-config.xml");
    }

  

另外一種方式:任務類必須繼承QuartzJobBean或者實現Job方法。

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.mc.bsframe.job.TestJob"></property>
        <property name="durability" value="true"></property>
    </bean>

    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail" />
        <property name="startDelay" value="3000" />
        <property name="repeatInterval" value="2000" />
    </bean>

    <!-- 總管理類 如果將lazy-init='false'那么容器啟動就會執行調度程序 -->
    <bean id="DefaultQuartzScheduler" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 管理trigger -->
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger" />
            </list>
        </property>
      <property name="configLocation" value="classpath:quartz.properties" />
</bean>

只持久化jobDetail

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.sky.JobSchedule.Job.HelloQuartzJob"></property>
        <property name="durability" value="true"></property>
    </bean>

    <bean id="DefaultQuartzScheduler" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
            <list>
                <ref bean="jobDetail" />
            </list>
        </property>
        <property name="configLocation" value="classpath:quartz.properties" />
    </bean>

  

兩種方法的說明

使用QuartzJobBean,需要繼承。而使用MethodInvokeJobDetailFactoryBean則需要指定targetObject(任務實例)和targetMethod(實例中要執行的方法)

后者優點是無侵入,業務邏輯簡單,一目了然,缺點是無法持久化(目前還不太清楚這點!)

從我使用的經驗來說,我更推薦的第二種,其中一個很重要的原因就是因為定時任務中注入相關Service的時候,后者可以直接注入,而前者還需要進行Schedular的替換修改。

 

上述配置的SchedulerFactoryBean的Id需要注意的是:

假若需要進行可視化調度管理的話,不可缺的是獲取所有的jobDetail等等,這時候需要注意的是,獲取過程中,實例化Scheduler時,instanceName會根據quartz.properties來進行獲取,沒有的話默認“QuartzSchelduer”,會獲取數據庫中SCHED_NAME一致的數據。

自定義的名字,可以直接保持配置的id和instanceName一致。

或者顯示的調用SchedulerFactoryBean:

StdSchedulerFactory sf = new StdSchedulerFactory();
Properties props = new Properties();
props.put("org.quartz.scheduler.instanceName", "你定義的名字");
props.put("org.quartz.threadPool.threadCount", "10");#必填
sf.initialize(props);
scheduler = sf.getScheduler();
System.out.println(scheduler.getSchedulerName());
scheduler.shutdown();

  

添加監聽器:在spring-quartz中,監聽器:http://www.cnblogs.com/skyLogin/p/6928431.html

<?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.xsd">

    <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.sky.JobSchedule.Job.HelloQuartzJob"></property>
        <property name="durability" value="true"></property>
    </bean>
    <bean id="jobDetail2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.sky.JobSchedule.Job.JobCron"></property>
        <property name="name" value="test2"></property>
        <property name="durability" value="true"></property>
        <property name="jobDataAsMap">
            <map>
                <entry key="name" value="sky"></entry>
            </map>
        </property>
    </bean>

    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail" />
        <property name="repeatInterval" value="2000" />
    </bean>
    <bean id="jobCountListener" class="com.sky.JobSchedule.Listener.JobCountListener" />
    <!--id-->
    <bean id="DefaultQuartzScheduler" lazy-init="false"  autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--<property name="autoStartup" value="false"></property>-->
        <property name="jobDetails">
            <list>
                <ref bean="jobDetail" />
                <ref bean="jobDetail2" />
            </list>
        </property>
        <!-- 管理trigger -->
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger" />
            </list>
        </property>
        <property name="configLocation" value="classpath:quartz.properties" />
        <property name="globalJobListeners" ref="jobCountListener"></property>
    </bean>
</beans>

  

quartz啟動流程

當服務器啟動時,就會裝載相關的bean。SchedulerFactoryBean實現了InitializingBean接口,因此在初始化bean的時候,會執行afterPropertiesSet方法,該方法將會調用SchedulerFactory(DirectSchedulerFactory 或者 StdSchedulerFactory,通常用StdSchedulerFactory)創建Scheduler。SchedulerFactory在創建quartzScheduler的過程中,將會讀取配置參數,初始化各個組件

  1. ThreadPool:一般是使用SimpleThreadPool,SimpleThreadPool創建了一定數量的WorkerThread實例來使得Job能夠在線程中進行處理。WorkerThread是定義在SimpleThreadPool類中的內部類,它實質上就是一個線程。在SimpleThreadPool中有三個list:workers-存放池中所有的線程引用,availWorkers-存放所有空閑的線程,busyWorkers-存放所有工作中的線程;

  2. JobStore:分為存儲在內存的RAMJobStore和存儲在數據庫的JobStoreSupport(包括JobStoreTX和JobStoreCMT兩種實現,JobStoreCMT是依賴於容器來進行事務的管理,而JobStoreTX是自己管理事務),若要使用集群要使用JobStoreSupport的方式;

  3. QuartzSchedulerThread:

SchedulerFactoryBean還實現了SmartLifeCycle接口,因此初始化完成后,會執行start()方法,該方法將主要會執行以下的幾個動作:

  1. 創建ClusterManager線程並啟動線程:該線程用來進行集群故障檢測和處理,將在下文詳細討論;
  2. 創建MisfireHandler線程並啟動線程:該線程用來進行misfire任務的處理,將在下文詳細討論;
  3. 置QuartzSchedulerThread的paused=false,調度線程才真正開始調度;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM