web-dev-qa-db-fra.com

Pourquoi Spring n'exécute-t-il pas ma méthode @Scheduled?

Je suis un peu confus parce que j'essaie d'utiliser les annotations @Scheduled, mais Spring ne semble pas avoir trouvé mes méthodes. Le résultat final est qu’aucune de mes méthodes annotées avec @Scheduled n’est exécutée.

J'ai invoqué la tâche magique 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 à quelque chose comme ça:

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 qui me dit quelle heure il est toutes les 5 secondes ... mais en réalité, je ne reçois absolument rien. J'ai essayé avec les annotations 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 en cours d'initialisation, car mon journal contient les informations suivantes:

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 la phrase sur le fait de ne pas être éligible est pertinente ou un casse-tête.

Pour le moment, je travaille autour de cela en déclarant mes tâches planifiées comme suit:

<task:scheduled-tasks>
  <task:scheduled ref="sourceDocumentManagerImpl" method="deleteOldDocuments" cron="0 0 * * * ?"/>
</task:scheduled-tasks>

Bien que cela fonctionne parfaitement, je préférerais de beaucoup utiliser les annotations car il est bien plus pratique de voir directement dans le code ce que l'on attend de cette méthode. Quelqu'un sait ce que je pourrais faire mal? Pour mémoire, j'utilise Spring 3.0.4

Merci beaucoup!

22
stevevls

Donc ... il semble y avoir un problème dans Spring 3.0.x (au moins 3.0.4 et 3.0.5) lié à la découverte des annotations @Scheduled sur les proxies AOP. J'ai une déclaration qui coupe la méthode @Scheduled avec des conseils transactionnels, et cela semble être la source du problème. Si je supprime l'avis, le travail est exécuté. Si je le rajoute, Spring ne parvient pas à trouver et à créer une tâche pour ma méthode annotée.

Donc, je vais déposer un bogue avec les gens de Spring, et entre-temps je suis bloqué pour déclarer mes tâches manuellement.

12
stevevls

ajouter "tâche: piloté par l'annotation"?

<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 des annotations

Ajoutez simplement @EnableScheduling sur votre classe WebMvcConfig

@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
   /** Annotations config Stuff ... **/
}

référence Spring Scheduler ne fonctionne pas

15
ahll

Malgré le fait que j'utilise Spring 3.1.2, je rencontre le même problème au cas où je placerais mon tag exécuteur et programmateur dans ApplicationContext.xml. J'ai deux fichiers de configuration XML pour le printemps dans mon projet qui sont: 

  1. applicationContext.xml
  2. dispatcher-servlet.xml

Essayez donc de déplacer votre configuration vers le dernier fichier de configuration lu par spring. dans mon cas, il faut commencer à travailler en déplaçant ma configuration vers dispatcher-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>

dispatcher-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.

4
Hazhir

Je l'ai corrigé en ajoutant default-lazy-init = "false" à mon applicationContext.xml.

<beans .....
    **default-lazy-init="false"**>
3
Aman Ghrera

La seule différence que je vois dans ma configuration (qui fonctionne) est que ma classe est annotée avec @Component plutôt que @Service. Autres choses à vérifier:

  • si vous avez les bons pots sur le classpath (printemps-contexte, je pense)
  • mettre un point d'arrêt et vérifier si cela ne s'exécute pas vraiment
  • revérifiez l'expression de cron (j'avoue que je consulte toujours la documentation pour cela). Ou utilisez un délai fixe, juste pour vérifier si cela fonctionne
  • essayez de passer à la version 3.0.5 ou au dernier instantané 3.1.
2
Bozho

Je résous le problème en supprimant use-default-filters = "false" dans le contexte composant-scan Ma vieille 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>

ma version de printemps 3.2.3

1
user2416625

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 au bas de mon applicationContext.xml:

<tx:annotation-driven/>
0
Mike