Pourquoi Spring n'exécute-t-il pas ma méthode @ Scheduled ?
Je suis un peu embrouillé parce que j'essaie d'utiliser use @Scheduled
annotations, mais Spring ne semble pas trouver mes méthodes. Le résultat final est qu'aucune de mes méthodes annotées avec @Scheduled
n'est en cours d'exécution.
J'ai invoqué la magie des tâches de Spring avec les déclarations suivantes:
<beans> <!-- XMLNS, XSD declarations omitted for brevity -->
<context:component-scan base-package="com.mypackage"/>
<task:executor id="executor" pool-size="5"/>
<task:scheduler id="scheduler" pool-size="5"/>
<task:annotation-driven scheduler="scheduler" executor="executor"/>
</beans>
Et j'ai une interface qui ressemble à ceci:
package com.mypackage;
public interface MyInterface {
public void executePeriodically();
}
Avec un impl correspondant comme ceci:
package com.mypackage.impl;
// imports omitted for brevity
@Service
public class MyInterfaceImpl implements MyInterface {
@Scheduled(cron = "0/5 * * * * ?")
public void executePeriodically() {
System.out.println("The time is now : " + new Date());
}
}
Maintenant, le résultat attendu est que j'ai un petit gars très bruyant me dire quelle heure il est toutes les 5 secondes...mais en réalité, Je ne reçois absolument rien. J'ai essayé avec l'annotation sur la méthode interface et sur la méthode impl, mais cela ne semble rien changer.
Je sais avec certitude que l'exécuteur et le planificateur sont initialisés car j'ai ce qui suit dans mon journal:
INFO - ThreadPoolTaskExecutor - Initializing ExecutorService
INFO - XmlWebApplicationContext - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO - XmlWebApplicationContext - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO - ThreadPoolTaskScheduler - Initializing ExecutorService 'scheduler'
INFO - XmlWebApplicationContext - Bean 'scheduler' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Je ne suis pas sûr si cette ligne sur ne pas être admissible est pertinente ou un hareng rouge.
En ce moment, je travaille autour d'elle en déclarant mon tâches planifiées comme ceci:
<task:scheduled-tasks>
<task:scheduled ref="sourceDocumentManagerImpl" method="deleteOldDocuments" cron="0 0 * * * ?"/>
</task:scheduled-tasks>
Bien que cela fonctionne parfaitement, je préfère utiliser les annotations car il est beaucoup plus pratique de voir directement dans le code quelles sont les attentes pour cette méthode. Quelqu'un sait ce que je pourrais faire de mal? Pour mémoire, J'utilise Spring 3.0.4
Merci beaucoup!
7 réponses
So...it on dirait qu'il y a un problème dans Spring 3.0.x (à tout le moins 3.0.4 et 3.0.5) ayant à voir avec la découverte des annotations @Scheduled
sur les proxies AOP. J'ai une déclaration pointcut enveloppant la méthode @Scheduled
avec des conseils transactionnels, et cela semble être la racine du problème. Si je supprime le Conseil, le travail s'exécute. Si je l'ajoute, Spring ne parvient pas à trouver et à créer une tâche pour ma méthode annotée.
Donc, je vais aller déposer un bug avec les gens de printemps, et dans le en attendant, je suis bloqué en déclarant mes tâches manuellement.
Ajouter "de la tâche:annotation-driven" ?
<beans> <!-- XMLNS, XSD declarations omitted for brevity -->
<context:component-scan base-package="com.mypackage"/>
<task:annotation-driven/>
<task:executor id="executor" pool-size="5"/>
<task:scheduler id="scheduler" pool-size="5"/>
<task:annotation-driven scheduler="scheduler" executor="executor"/>
</beans>
Référence http://howtodoinjava.com/2013/04/23/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/
Ou
Spring @ Configuration (configuration non xml) pour les tâches pilotées par les annotations
Ajoutez simplement @EnableScheduling sur votre classe WebMvcConfig
@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/** Annotations config Stuff ... **/
}
Malgré cela, j'utilise Spring 3.1.2, je rencontre le même problème au cas où je placerais mon exécuteur et ma balise scheduler dans ApplicationContext.XML. j'ai deux fichiers de configuration xml pour spring dans mon projet qui sont:
- applicationContext.xml
- répartiteur-servlet.xml
Essayez donc de déplacer votre configuration vers le dernier fichier de configuration que spring lit. dans mon cas, il commence à travailler en déplaçant ma configuration vers répartiteur-servlet.xml
Voici mon exemple:
ApplicationContext.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="/WEB-INF/configuration.properties" />
</bean>
<!-- To fix the problem with Unicode characters in ajax responses -->
<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<array>
<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
<bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
</array>
</property>
</bean>
<!-- Hibernate Configuration
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/iss"
p:username="root"
p:password="root"
-->
<bean name="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="org.postgresql.Driver"
p:url="jdbc:postgresql://localhost:5432/iss"
p:username="postgres"
p:password=""
/>
<!--<bean name="SessionFactory" class="org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean">-->
<bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="DataSource" />
</property>
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<!--<prop key="hibernate.current_session_context_class">thread</prop>-->
<!--<prop key="hibernate.current_session_context_class">managed</prop>-->
<!--<prop key="hibernate.search.default.indexBase">/tmp/hibernate/indexes/</prop>-->
<!--<prop key="hibernate.flushMode">AUTO</prop>-->
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
<property name="packagesToScan" value="iss.DB" />
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<mvc:interceptors>
<bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</mvc:interceptors>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
<!-- in this file it wont work
<task:executor id="myExecutor" pool-size="1" />
<task:scheduler id="myScheduler" pool-size="1" />
<task:annotation-driven
executor="myExecutor"
scheduler="myScheduler"/>
-->
</beans>
Répartiteur-servlet.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
xmlns:context="http://www.springframework.org/schema/context">
<bean class="org.springframework.web.servlet.mvc.support.AnnotationControllerTypePredicate"/>
<context:component-scan base-package="iss"/>
<context:component-scan base-package="com.hazhir"/>
<!--Internationalization -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="iss.languages.text" />
</bean>
<bean id="localChangeInterseptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en_US" />
<property name="cookieName" value="clientLanguage" />
<property name="cookieMaxAge" value="99999999"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="alwaysUseFullPath" value="true" />
<property name="interceptors">
<list>
<ref bean="localChangeInterseptor" />
</list>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp">
<property name="exposeContextBeansAsAttributes" value="true" />
</bean>
<!-- Multipart form data -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1000000000" />
</bean>
<context:annotation-config />
<!-- here is a right place for such configuration
-->
<task:executor id="myExecutor" pool-size="1" />
<task:scheduler id="myScheduler" pool-size="1" />
<task:annotation-driven
executor="myExecutor"
scheduler="myScheduler"/>
</beans>
J'espère que ça aide.
Je l'ai corrigé en ajoutant default-lazy-init= "false" à mon applicationContext.XML.
<beans .....
**default-lazy-init="false"**>
La seule différence que je vois de ma configuration (qui fonctionne), c'est que ma classe est annotée avec @Component
plutôt que @Service
. Autres choses à vérifier:
- Si vous avez les jars appropriés sur le classpath (spring-context, je pense)
- Mettez un point d'arrêt et vérifiez s'il ne s'exécute pas vraiment
- revérifiez l'expression cron (j'avoue que je consulte toujours les docs pour cela). Ou utilisez un délai fixe, juste pour vérifier si cela fonctionne
- essayez de mettre à niveau vers la version 3.0.5 ou la dernière version 3.1 instantané.
Je le résous en supprimant use-default-filters= "false" dans le contexte: component-scan mon ancienne configuration est
<context:component-scan base-package="com.XXXx" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
Mon printemps version 3.2.3
J'ai résolu en ajoutant les deux:
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
Puis:
<!-- TASK -->
<task:scheduler id="searchScheduler" pool-size="1"/>
<task:executor id="searchExecutor" pool-size="1"/>
<task:annotation-driven executor="searchExecutor" scheduler="searchScheduler"/>
Et dans le bootom de mon applicationContext.xml:
<tx:annotation-driven/>