TaskExecutionandScheduling
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>SpringContext</description> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>当然,需要告诉Spring去哪儿扫描组件。对了,也要告诉Spring我们是使用注解方式注册任务的
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/taskhttp://www.springframework.org/schema/task/spring-task-3.2.xsd"> <context:component-scanbase-package="com.nicchagil.*"/> <task:annotation-driven/> </beans>附logback的配置
<configuration> <appendername="STDOUT"class="ch.qos.logback.core.ConsoleAppender"> <!--encodersareassignedthetypech.qos.logback.classic.encoder.PatternLayoutEncoder bydefault--> <encoder> <pattern>%d{HH:mm:ss.SSS}[%thread]%-5level%logger{36}-%msg%n </pattern> </encoder> </appender> <appendername="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> <rootlevel="debug"> <appender-refref="STDOUT"/> <appender-refref="FILE"/> </root> </configuration>好了,注册一个简单的任务,它每逢0秒执行,打印一个语句
packagecom.nicchagil.springtask; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; @Component publicclassMyFirstSpringJob{ privatefinalLoggerlogger=LoggerFactory.getLogger(this.getClass()); @Scheduled(cron="0****?") publicvoidrun(){ logger.info("MyFirstSpringJobtrigger..."); } }如无意外,启动项目后,可见日志大致如下
22:42:00.024[pool-1-thread-1]INFO c.n.springtask.MyFirstSpringJob-MyFirstSpringJobtrigger... 22:43:00.002[pool-1-thread-1]INFO c.n.springtask.MyFirstSpringJob-MyFirstSpringJobtrigger...如题。比如,你设置了12:00触发A任务、12:05触发B任务,如果A任务需耗时10分钟,并且没设置线程池,那么B任务有可能会被推迟到12:10以后再执行哦。
所以,这些情况,我们需设置线程池
<task:annotation-drivenscheduler="myScheduler"/> <task:schedulerid="myScheduler"pool-size="20"/>注:具体池的大小,视项目情况而定
将任务改为如下测试
第一个任务
packagecom.nicchagil.springtask; importjava.util.concurrent.TimeUnit; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; @Component publicclassMyFirstSpringJob{ privatefinalLoggerlogger=LoggerFactory.getLogger(this.getClass()); @Scheduled(cron="0****?") publicvoidrun(){ logger.info("MyFirstSpringJobtrigger..."); /*模拟此Job需耗时5秒*/ try{ TimeUnit.SECONDS.sleep(5); }catch(InterruptedExceptione){ e.printStackTrace(); } } }第二个任务
packagecom.nicchagil.springtask; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; @Component publicclassMySecondSpringJob{ privatefinalLoggerlogger=LoggerFactory.getLogger(this.getClass()); @Scheduled(cron="3****?") publicvoidrun(){ logger.info("MySecondSpringJobtrigger..."); } }由日志可以看出,第一个任务由一个线程执行;而第二个任务启动时,由于第一个任务还未完成,则由另外一个线程执行
22:49:00.023[myScheduler-1]INFOc.n.springtask.MyFirstSpringJob-MyFirstSpringJobtrigger... 22:49:03.002[myScheduler-2]INFOc.n.springtask.MySecondSpringJob-MySecondSpringJobtrigger...本文内容总结:>参考的优秀文章,>版本说明,>搭建最简单的Spring定时任务工程,>如果你同时执行多个任务,且某些任务耗时较长,要配线程池哦(>_<),
原文链接:https://www.cnblogs.com/nick-huang/p/4864737.html