【Spring】Spring的定時任務

> 參考的優秀文章

Task Execution and Schedulinghtml

 

> 版本說明

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.14.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.webflow</groupId>
        <artifactId>spring-webflow</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.0</version>
    </dependency>
</dependencies>

 

> 搭建最簡單的Spring定時任務工程

Spring定時任務,給人的第一感受就是簡潔(>_<)java

所須要的JAR,參考以上「版本說明」的POM文件,固然,不嫌麻煩,也能夠一個個去下載。web

把Spring經過web.xml註冊進來spring

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:spring/spring.xml</param-value>
</context-param>

<listener>
    <description>Spring Context</description>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 

固然,須要告訴Spring去哪兒掃描組件。對了,也要告訴Spring咱們是使用註解方式註冊任務的spring-mvc

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

    <context:component-scan base-package="com.nicchagil.*"/>
    <task:annotation-driven/>
    
</beans>

 

附logback的配置mvc

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder 
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>D:/logs/application.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

 

好了,註冊一個簡單的任務,它每逢0秒執行,打印一個語句app

package com.nicchagil.springtask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyFirstSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "0 * * * * ?")
    public void run() {
        logger.info("MyFirstSpringJob trigger...");
    }

}

 

如無心外,啓動項目後,可見日誌大體以下測試

22:42:00.024 [pool-1-thread-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...
22:43:00.002 [pool-1-thread-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...

 

> 若是你同時執行多個任務,且某些任務耗時較長,要配線程池哦(>_<)

如題。好比,你設置了12:00觸發A任務、12:05觸發B任務,若是A任務需耗時10分鐘,而且沒設置線程池,那麼B任務有可能會被推遲到12:10之後再執行哦。this

因此,這些狀況,咱們需設置線程池spa

<task:annotation-driven scheduler="myScheduler"/>
<task:scheduler id="myScheduler" pool-size="20"/>

:具體池的大小,視項目狀況而定

 

將任務改成以下測試

第一個任務

package com.nicchagil.springtask;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyFirstSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "0 * * * * ?")
    public void run() {
        logger.info("MyFirstSpringJob trigger...");
        
        /* 模擬此Job需耗時5秒 */
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

 

第二個任務

package com.nicchagil.springtask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MySecondSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "3 * * * * ?")
    public void run() {
        logger.info("MySecondSpringJob trigger...");
    }

}

 

由日誌能夠看出,第一個任務由一個線程執行;而第二個任務啓動時,因爲第一個任務還未完成,則由另一個線程執行

22:49:00.023 [myScheduler-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...
22:49:03.002 [myScheduler-2] INFO  c.n.springtask.MySecondSpringJob - MySecondSpringJob trigger...
相關文章
相關標籤/搜索