Home  >  Article  >  Java  >  Detailed explanation of spring scheduled task @Scheduled

Detailed explanation of spring scheduled task @Scheduled

高洛峰
高洛峰Original
2017-02-07 15:39:052658browse

1. Configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:task="http://www.springframework.org/schema/task"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"
 default-autowire="byName" default-lazy-init="false">
 
 <!-- 定时任务相关配置 -->
 <task:executor id="executor" pool-size="10" queue-capacity="128"/>
 <task:scheduler id="scheduler" pool-size="10"/>
 <task:annotation-driven executor="executor" scheduler="scheduler" proxy-target-class="true"/>
 
</beans>

2. Call

There are two ways to use it

1) If you need to execute at a fixed rate, just Just change the attribute name specified in the annotation to fixedRate. The following method will be called and executed at a fixed rate of 5s. This cycle is based on the start time of the previous task and will be called again 5s after the start of the previous task:

@Scheduled(fixedDelay = 5000)
 public void testTask() {
  logger.info("测试定时任务");
 }

2) Using cron expressions, you can implement scheduled calls, such as: calling every morning. Detailed cron related parameters will be introduced later

@Scheduled(cron = "cron = "0 0 2 * * ?"")
 public void testTaskWithDate() {
  logger.info("测试2016.定时任务");
 }

3 , Meaning of cron related parameters

A cron expression has at least 6 (maybe 7) time elements separated by spaces.

In order, they are

Seconds (0~59)

Minutes (0~59)

Hours (0~23)

 Day (month) (0~31, but you need to consider the number of days in your month)

 Month (0~11)

 Day (week) (1~7 1=SUN or SUN, MON, TUE, WED, THU, FRI, SAT)

Year (1970-2099) - @Scheduled is not supported, spring quartz supports

each of them The element can be a value (such as 6), a continuous interval (9-12), an interval (8-18/4) (/ means every 4 hours), a list (1, 3, 5), or a wildcard. Since the two elements "day of month" and "day of week" are mutually exclusive, one of them must be set?.

 0 0 10,14,16 * * ? Every day at 10 a.m. , 2pm, 4pm

 0 0/30 9-17 * * ? Every half hour during 9 to 5 working hours

 0 0 12 ? *WED means every Wednesday at noon 12 o'clock

 "0 0 12 * * ?" Triggered at 12 noon every day

 "0 15 10 ? * *" Triggered at 10:15 am every day

 "0 15 10 *** Trigger every day at 10:15 am

 "0 * 14 * * ?" Trigger every 1 minute from 2 pm to 2:59 pm every day

 "0 0/5 14 * * ?" Triggers every 5 minutes from 2 pm to 2:55 pm every day

 "0 0/5 14,18 * * ?" Triggers every 5 minutes from 2 pm to 2:55 pm every day and at 6 pm Trigger every 5 minutes from 2:00 pm to 2:05 pm

 "0 0-5 14 * * ?" Trigger every 1 minute from 2 pm to 2:05 pm every day

 "0 10,44 14 ? 3 WED" Triggers every Wednesday in March at 2:10 and 2:44 pm

 "0 15 10 ? * MON-FRI" Triggers at 10:15 am from Monday to Friday

 "0 15 10 15 * ?" Triggered at 10:15 am on the 15th of each month

 "0 15 10 L * ?" Triggered at 10:15 am on the last day of each month

 "0 15 10 ? * 6L" Triggered at 10:15 am on the last Friday of each month

 "0 15 10 ? * 6L 2002-2005" The last day of each month from 2002 to 2005 Triggers at 10:15 am on Friday

 "0 15 10 ? * 6#3" Triggers at 10:15 am on the third Friday of each month

Some subexpressions can contain some ranges or lists

For example: the sub-expression (day (week)) can be "MON-FRI", "MON, WED, FRI", "MON-WED, SAT"

"*" character Represents all possible values

Therefore, "*" in the sub-expression (month) represents the meaning of each month, and "*" in the sub-expression (day (week)) represents each day of the week

The "/" character is used to specify the increment of the value

For example: "0/15" in the subexpression (minutes) means starting from the 0th minute , every 15 minutes

The "3/20" in the subexpression (minutes) means that starting from the 3rd minute, every 20 minutes (it has the same meaning as "3, 23, 43")

 "? " character is only used in the two sub-expressions of day (month) and day (week), indicating that no value is specified

When one of the two sub-expressions is specified with a value, in order to avoid conflicts, it needs to be The value of another subexpression is set to "? "


The "L" character is only used in the two sub-expressions of day (month) and day (week). It is the abbreviation of the word "last"

But Its meaning in the two sub-expressions is different.

In the day (month) sub-expression, "L" represents the last day of the month

In the day (week) since In the expression, "L" represents the last day of the week, which is SAT

If there is specific content before "L", it has other meanings

For example: " 6L" means the 6th to last day of this month, "FRIL" means the last Friday of this month

Note: When using the "L" parameter, do not specify a list or range, as this will cause problems

4. Limitations - @Scheduled's cron cannot specify the year of execution

spring 定时任务@Scheduled详解That is, if we use the following scheduled task

@Scheduled(cron = "0 18 10 * * ? 2016-2016")
  public void testTaskWithDate() {
    logger.info("测试2016.定时任务");
  }

The following error will be reported

Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")

org.springframework.beans.factory.BeanCreationException: Error creating bean with name &#39;giftReceiveRecordServiceImp&#39; defined in URL [jar:file:/Users/zhengcanrui/WORK/git/seewoedu-train-server/train-web/target/train/WEB-INF/lib/train-server-2.0-SNAPSHOT.jar!/com/seewoedu/train/service/impl/GiftReceiveRecordServiceImp.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method &#39;testTaskWithDate&#39;: Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
 at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
 at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
 at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
 at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842)
 at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
 at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
 at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
 at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1696)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
 at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
 at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
 at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:484)
 at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:433)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
 at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
 at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
 at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487)
 at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
 at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
 at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
 at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
 at sun.rmi.transport.Transport$2.run(Transport.java:202)
 at sun.rmi.transport.Transport$2.run(Transport.java:199)
 at java.security.AccessController.doPrivileged(Native Method)
 at sun.rmi.transport.Transport.serviceCall(Transport.java:198)
 at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(TCPTransport.java:619)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:684)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:681)
 at java.security.AccessController.doPrivileged(Native Method)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method &#39;testTaskWithDate&#39;: Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")
 at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:405)
 at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:258)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
 ... 58 more

错误原因:

/**
 * Parse the given pattern expression.
 */
private void parse(String expression) throws IllegalArgumentException {
 String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
 if (fields.length != 6) {
  throw new IllegalArgumentException(String.format(""
    + "cron expression must consist of 6 fields (found %d in %s)", fields.length, expression));
 }

spring taks 不支持年位定时,它毕竟不是quartz,只是简单的定时框架,比起jdk Timer就加入了线程池而以.

但是制定到年份,会存在一个问题,就是在你在过了这个时间后再启动项目的时候,他会一直报一个memory leak的错误,大概的意思是你的定时任务将永远不会被执行,导致项目一直启动不了。

源码里的注释:

 *The pattern is a list of six single space-separated fields: representing
 * second, minute, hour, day, month, weekday. Month and weekday names can be
 * given as the first three letters of the English names.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

更多spring 定时任务@Scheduled详解相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn