1. 程式人生 > >spring框架使用Quartz執行定時任務例項詳解

spring框架使用Quartz執行定時任務例項詳解

Quartz簡介

  1.Quartz,是一個完全由java編寫的開源作業排程框架。它包含了排程器監聽、作業和觸發器監聽,而我們在專案中最常用到的就是它可以作為一個定時器,可以隨時配置監聽、觸發任務進行作業。
  2.在Spring的框架裡,Quartz已經被很好地整合,我們只需要在xml檔案裡面配一下定時時間就可以自動執行任務了。
  3.本部落格主要介紹的是一個quartz專案的完整的搭建、配置以及成功執行的過程,裡面包含了多個定時器的配置以及多個數據庫的配置方法,非常適合新手去接觸和掌握quartz的使用而且還附有完整的quartz定時器專案例項下載,專案下載地址:QuartzTask定時器專案例項

專案例項詳解

  1.首先我們看一下整個專案的結構,最基本的spring架構:
 這裡寫圖片描述
  2.接下來我們將逐個步驟去搭建、配置以及執行這個專案,每個步驟在專案裡面我都配有詳細的說明,
   (1)首先,我們看一下web.xml配置: 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class
>
</listener> <!-- 載入spring配置檔案 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext*.xml</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

   (2)其次,我們看一下載入的spring配置檔案applicationContext.xml配置: 

    <!-- 載入配置屬性檔案,資料庫檔案 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:/jdbc.properties" />

    <!-- 使用Annotation自動註冊Bean -->
    <context:component-scan base-package="com.hqc"><!-- base-package 如果多個,用“,”分隔 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 資料來源可自行配置新增多個,這裡只演示postgresql和mysql資料來源示例,需要哪些可自行新增測試,都是經過實踐成功的-->
    <!-- Postgresql資料庫連線配置 -->
    <bean id="postgresqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver"></property>
        <property name="url" value="jdbc:postgresql://localhost:2345/jftest"></property>
        <property name="username" value="postgres"></property>
        <property name="password" value="1234"></property>
        <property name="initialSize" value="20"></property>
        <property name="maxActive" value="20"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <!-- Mysql資料庫連線配置-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">
      <property name="driverClassName" value="${jdbc.driver}" /> 
      <property name="url" value="${jdbc.url}" /> 
      <property name="username" value="${jdbc.username}" />       
      <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- oracle資料庫連線配置, 使用 BoneCP資料庫連線池 
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.pool.init}" />
        <property name="minIdle" value="${jdbc.pool.minIdle}" /> 
        <property name="maxActive" value="${jdbc.pool.maxActive}" />
        <property name="maxWait" value="60000" />
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="validationQuery" value="${jdbc.testSql}" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="filters" value="stat" /> 
    </bean>-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>

    <!-- Greenplum資料庫連線配置 
    <bean id="postgresqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.pivotal.jdbc.GreenplumDriver"></property>
        <property name="url" value="jdbc:pivotal:greenplum://localhost:2345;DatabaseName=jftest"></property>
        <property name="username" value="greenplum"></property>
        <property name="password" value="1234"></property>
        <property name="initialSize" value="20"></property>
        <property name="maxActive" value="20"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>-->

    <!-- 定時器1 -->
    <bean id="taskTrigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail">
            <bean
                class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
                <property name="targetObject">
                    <bean class="com.hqc.service.DataStaticService"></bean><!--目標類-->
                </property>
                <property name="targetMethod" value="testMethod1" /><!--目標方法-->
                <property name="concurrent" value="false" />
            </bean>
        </property>
        <property name="cronExpression">
            <!-- 秒、分、時、日期、月份、星期、年 -->
            <!-- 具體的更多的寫法可以參照:https://blog.csdn.net/alan_liuyue/article/details/80222565 -->
            <value>0/5 * * * * ? </value>  <!-- 每五秒執行一次 -->
        </property>
    </bean>

    <!-- 定時器2-->
    <bean id="taskTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail">
            <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
                <property name="targetObject">
                    <bean class="com.hqc.service.DataStaticService"></bean>
                </property>
                <property name="targetMethod" value="testMethod2" />
                <property name="concurrent" value="false" />
            </bean>
        </property>
        <property name="cronExpression">
             <value>0 0 0/1 * * ?</value> <!-- 每一小時執行一次 -->
        </property>
    </bean>



    <!-- 總排程用於啟動Spring定時器,可以啟動多個,需要啟動哪一個就去掉註釋即可-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="taskTrigger1" /> <!--排程第一個定時任務 -->
                <ref bean="taskTrigger2" /> <!--排程第二個定時任務 -->
            </list>
        </property>
    </bean>

   (3)然後,就是資料庫的配置檔案jdbc.properties,這個檔案可以將所有的資料庫連線屬性都寫在裡面,當然你也可以直接在applicationContext.xml裡面直接配置資料庫資訊,一個專案可以配置多個數據源,相信大家都是沒問題的:

##oracle資料庫配置
#jdbc.type=oracle
#jdbc.driver=oracle.jdbc.driver.OracleDriver
#jdbc.url=jdbc:oracle:thin:@localhost:1521:testora
#jdbc.username=test
#jdbc.password=test
##pool settings
#jdbc.pool.init=10
#jdbc.pool.minIdle=30
#jdbc.pool.maxActive=50
##jdbc.testSql=SELECT 'x'
#jdbc.testSql=SELECT 'x' FROM DUAL

#mysql資料庫配置
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/jftest?useSSL=false&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=1234

   (4)接下來我們再講一下專案裡面的各個檔案的作用,這裡直接用一張圖給大家進行展示說明:
   這裡寫圖片描述
   (5)我們看一下在配置檔案裡quartz指定的定時執行的方法:

/**
 * 
 * @author hqc
 * @version 2018年05月20日
 *
 */
public class DataStaticService {
    protected static Logger logger = Logger.getLogger(DataStaticService.class);

    @Autowired
    DataPostgresqlDao dataPostgresqlDao;

    @Autowired
    DataOracleDao dataOracleDao;

    /**
     * 測試定時方法1
     */
    public void testMethod1(){
        Calendar c = Calendar.getInstance();
        String today = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()); 
        System.out.println("定時任務程式執行時間:"+today);
        System.out.println("定時查詢oracle庫t_user表的資料數量:"+dataOracleDao.queryTest().size());    
    }

    /**
     * 測試定時方法2
     */
    public void testMethod2(){
        Calendar c = Calendar.getInstance();
        String today = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()); 
        //昨天的當前時間
//      c.add(Calendar.DATE, -1);
//      String yesterday = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime());
        System.out.println("定時任務程式執行時間:"+today);
        System.out.println("定時查詢postgresql庫t_user表的資料數量:"+dataPostgresqlDao.queryTest().size());

    }

}

   (6)最後,我們看一下定時任務執行的效果,這裡我設定的是每5秒執行一次:
   這裡寫圖片描述

總結

  1.好了,以上就是spring框架使用Quartz執行定時任務完整例項詳解,很適合新手去熟悉和掌握quartz;
  2.實踐是認識真理性的唯一標準,通過這一個簡單的專案實踐,有興趣的小夥伴們能繼續去深入研究,從而形成一套適合自己的定時器專案,在專案中運用的時候就會事半功倍;