Maison  >  Article  >  Java  >  Explication détaillée de la tâche planifiée au printemps @Scheduled

Explication détaillée de la tâche planifiée au printemps @Scheduled

高洛峰
高洛峰original
2017-02-07 15:39:052654parcourir

1. Fichier de configuration

<?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 Il existe deux façons d'appeler

1) Si vous devez exécuter à. un taux fixe, changez simplement le nom de l'attribut spécifié dans l'annotation en fixedRate. La méthode suivante sera appelée et exécutée à un taux fixe de 5 secondes. Ce cycle est basé sur l'heure de début de la tâche précédente et sera à nouveau appelé. 5 secondes après le début de la tâche précédente :

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

2) À l'aide d'expressions cron, vous pouvez implémenter des appels planifiés, tels que : appeler tous les matins. Les paramètres détaillés liés au cron sont. introduit plus tard

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

3. Signification des paramètres liés à cron

Une expression cron a au moins 6 (peut-être 7) éléments temporels séparés par des espaces.

Dans l'ordre :

Secondes (0~59)

Minutes (0~59)

Heures (0~23)

Jour (mois) (0~31, mais vous devez tenir compte du nombre de jours dans votre mois)

Mois (0~11)

Jour (semaine) (1~7 1 =SUN ou SUN, LUN, TUE, WED, THU, FRI, SAT)

Année (1970-2099) - @Scheduled n'est pas pris en charge, le quartz printanier prend en charge chacun des

L'élément peut être une valeur (telle que 6), un intervalle continu (9-12), un intervalle (8-18/4) (/ signifie toutes les 4 heures), une liste (1, 3, 5) ou des caractères génériques. . Les deux éléments "jour du mois" et "jour de la semaine" s'excluant mutuellement, il faut régler l'un d'entre eux ?.

 0 0 10,14,16 * * ? Tous les jours à 10h, 14h. , 16h

 0 0/30 9-17 * * ? Toutes les demi-heures pendant 9 à 5 heures ouvrables

  0 0 12 * MER signifie tous les mercredis à midi 12h

 "0 0 12 * * ?" Déclenché à 12h tous les jours

 "0 15 10 ? * *" Déclenché à 10h15 tous les jours

 "0 15 10 *** Déclenchement tous les jours à 10h15

 "0*14* * ?" Déclenchement toutes les 1 minutes de 14h à 14h59 tous les jours

 "0 0/5 14 * * ?" Déclenche toutes les 5 minutes de 14h à 14h55 tous les jours

 "0 0/5 14,18 * * ?" Déclenche de 14h à 14h55 et 18h tous les jours Déclenche toutes les 5 minutes de 14h00 à 14h05

 "0 0-5 14 * * ?" Déclenchement toutes les 1 minutes de 14h à 14h05 tous les jours

 "0 10, 44 14 ? 3 MER" Déclenchements tous les mercredis du mois de mars à 14h10 et 14h44

 "0 15 10 ? * LUN-VEN" Déclenchements à 10h15 du lundi au vendredi

 "0 15 10 15 * ?" Déclenché à 10h15 le 15 de chaque mois

 "0 15 10 L * ?" 🎜>

 "0 15 10 ? *6L" Déclenché à 10h15 le dernier vendredi de chaque mois

  "0 15 10 ? *6L 2002-2005" Le dernier jour de chaque mois à partir de 2002 à 2005 Déclenchements à 10h15 le vendredi

 "0 15 10 ? * 6#3" Déclenchements à 10h15 le troisième vendredi de chaque mois

Certaines sous-expressions peuvent contenir certaines plages ou listes

Par exemple : la sous-expression (jour (semaine)) peut être "MON-FRI", "MON, WED, FRI", "MON-WED,SAT"

Caractère "*" Représente toutes les valeurs possibles

Par conséquent, "*" dans la sous-expression (mois) représente la signification de chaque mois, et "*" dans la sous-expression (jour ( week)) représente chaque jour de la semaine

Le caractère "/" permet de préciser l'incrément de la valeur

Par exemple : "0/15" dans la sous-expression (minutes) signifie à partir de la 0ème minute, toutes les 15 minutes

Le "3/20" dans la sous-expression (minutes) signifie qu'à partir de la 3ème minute, toutes les 20 minutes (ça a la même signification comme "3, 23, 43")

 “ ? Le caractère " n'est utilisé que dans les deux sous-expressions de jour (mois) et jour (semaine), indiquant qu'aucune valeur n'est spécifiée

Lorsqu'une des deux sous-expressions est spécifiée avec une valeur, dans l'ordre pour éviter les conflits, il doit être La valeur d'une autre sous-expression est définie sur "? "


Le caractère "L" n'est utilisé que dans les deux sous-expressions de jour (mois) et jour (semaine). C'est l'abréviation du mot "dernier"

Mais sa signification dans les deux sous-expressions est différente. Dans la sous-expression jour (mois), "L" représente le dernier jour du mois

Dans la sous-expression jour (semaine). expression. Dans l'expression, "L" représente le dernier jour de la semaine, qui est SAT

S'il y a un contenu spécifique avant "L", il a d'autres significations

Par exemple : " 6L" signifie le 6ème au dernier jour du mois, "FRIL" signifie le dernier vendredi du mois

REMARQUE : Lorsque vous utilisez le paramètre "L", ne spécifiez pas de liste ou de plage, car cela entraînerait problèmes

4. Limitations - Le cron de @Scheduled ne peut pas spécifier l'année d'exécution

C'est-à-dire si nous utilisons la tâche planifiée suivante

spring 定时任务@Scheduled详解

L'erreur suivante sera signalée

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中文网!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn