首页 > 代码库 > Spring 定时任务2

Spring 定时任务2

转载自http://www.cnblogs.com/nick-huang/p/4864737.html

> 版本说明

<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定时任务,给人的第一感觉就是简洁(>_<)

所需要的JAR,参考以上“版本说明”的POM文件,当然,不嫌麻烦,也可以一个个去下载。

把Spring通过web.xml注册进来

<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我们是使用注解方式注册任务的

<?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的配置

<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秒执行,打印一个语句

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以后再执行哦。

所以,这些情况,我们需设置线程池

<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;@Componentpublic 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;@Componentpublic 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...

Spring 定时任务2