2013-05-28 2 views
0

Je cours Spring 3.2.3.RELEASE et j'ai plusieurs méthodes dans les classes @Service décorées qui sont des tâches planifiées et donc décorées avec l'annotation @Scheduled.Le printemps ne détecte pas les méthodes @Scheduled

Tous les beans Spring sont détectés et instanciés dans le conteneur, mais les annotations @Scheduled ne sont jamais appelées.

J'ai plusieurs contextes d'application, mais le fichier principal est décrit ci-dessous comme suit:

<?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:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

    <import resource="classpath:core-properties.xml" /> 
    <import resource="classpath:core-datasource.xml" /> 
    <import resource="classpath:core-task-scheduler.xml" /> 

    <context:component-scan base-package="com.atlaschase.project.core"> 
     <context:exclude-filter type="regex" 
      expression="com.atlaschase.project.core.services.jms.*" /> 
     <context:exclude-filter type="regex" 
      expression="com.atlaschase.project.core.services.processor.*" /> 
     <context:exclude-filter type="regex" 
      expression="com.atlaschase.project.core.services.remote.*" /> 
     <context:exclude-filter type="regex" 
      expression="com.atlaschase.project.core.bootstrap.populators.*" /> 
    </context:component-scan> 

    <bean id="bufferPopulator" class="com.atlaschase.project.core.services.jms.buffer.BufferPopulator"/> 

    <bean id="eventBuffer" class="com.atlaschase.project.core.services.jms.buffer.EventBuffer"/> 

    <bean id="processorEventHandler" class="com.atlaschase.project.core.services.jms.buffer.ProcessorEventHandler"/> 

L'autre fichier important est importé comme « core-tâche scheduler.xml ». Ceci est configuré comme suit:

<?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:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/> 

    <task:executor id="myExecutor" pool-size="1"/> 

    <task:scheduler id="myScheduler" pool-size="5"/> 

</beans> 

A l'origine, la référence exécuteur testamentaire (ci-dessus) a été défini dans le principal contexte d'application, mais je divisé ceci comme une importation après avoir lu que d'autres problèmes similaires avaient été résolus de cette façon. Malheureusement, cela n'a pas aidé. J'ai également déplacé les déclarations d'importation, mais cela semble n'avoir aucun effet.

Déclaration Les méthodes planifiées dans Spring Application Context fonctionnent directement correctement, mais je souhaite vivement utiliser les annotations.

Voici la classe annotée:

** 
* Service that batches the saving of position updates into a periodically executed 
* process. 
*/ 
@Service 
public class PositionAggregatorService { 

    static Logger logger = Logger.getLogger(AircraftPositionAggregatorService.class); 

    // The service will not execute within 1 minute of a previous batch attempt. 
    // This paramater is updated by a message from another node indicating that 
    // they are commencing a batch save of position updates. 
    private DateTime blockingTime; 

    private Map<Long, List<Position>> positions; 

    @Autowired 
    private PositionDao positionDao; 

    @Autowired 
    private InternalPublisher internalEventPublisher; 

    @PostConstruct 
    private void initialise(){ 
     positions = new ConcurrentHashMap<Long, List<Position>>(); 
    } 

    /* 
    * Scheduled to execute every 10 minutes as long current time is not 
    * before the blocking time threshold. 
    * 
    * */ 
    @Scheduled(fixedRate=6000) 
    public void batchSavePositionUpdates(){ 

     if(blockingTime != null){ 
      if(DateTime.now(DateTimeZone.UTC).isBefore(blockingTime)){ 
       return; 
      } 
     } 

     PositionPersistStartedNotification started = new PositionPersistStartedNotification(DateTime.now(DateTimeZone.UTC), DateTime.now(DateTimeZone.UTC).plusMinutes(2)); 
     internalEventPublisher.publishPositionPersistStartedNotification(started); 

     DateTime mostRecentUpdateTime = null; 

     List<Position> positionsToSave = new ArrayList<Position>(); 

     for(Long flightId : positions.keySet()){ 

      List<Position> positionList = positions.get(flightId); 

      for(Position position : positionList){ 
       if(mostRecentUpdateTime == null){ 
        mostRecentUpdateTime = new DateTime(position.getTime()); 
       } 
       else{ 
        DateTime positionTime = new DateTime(position.getTime()); 
        if(positionTime.isAfter(mostRecentUpdateTime)){ 
         mostRecentUpdateTime = positionTime; 
        } 
       } 
       positionsToSave.add(position); 
      } 
     } 

     Boolean successfulSave = false; 

     try{ 
      positionDao.save(positionsToSave); 
      successfulSave = true; 
      logger.info(positionsToSave.size() + " Position Updates saved successfully"); 
     }catch(Exception exception){ 
      logger.error("Failed to persist latest position updates to database"); 
      logger.error(exception); 
     } 


     if(successfulSave){ 
      removeSavedPositions(mostRecentUpdateTime); 
      PositionPersistEndedNotification ended = new PositionPersistEndedNotification(DateTime.now(DateTimeZone.UTC), mostRecentUpdateTime); 
      internalEventPublisher.publishPositionPersistEndedNotification(ended); 
     } 

    } 
} 

Toute aide serait appréciée.

+0

Est-ce que vous filtrez par inadvertance votre classe annotée dans votre analyse de composants? Qu'est-ce que Spring dit qu'il fait quand il essaie d'autowire tout votre code? – DaveRlz

+0

J'appelle d'autres méthodes publiques directement dans le bean pendant l'exécution. Le bean existe dans le conteneur - c'est juste que les méthodes @Scheduled ne tirent pas. – totalcruise

+0

Pouvons-nous voir un exemple de classe qui utilise l'annotation '@ Scheduled'? –

Répondre

2

Le contexte Spring est-il chargé avec succès lors de l'exécution? Je vois que vous avez des incohérences dans les définitions d'espaces de noms où différentes versions coexistent dans le xsd (3.0 et 3.2). Pouvez-vous essayer d'avoir toujours la même version dans ces espaces de noms et réessayer?

0

L'application était démarrée en écoutant le contexte à charger, puis en exécutant une méthode sur ContextRefreshedEvent. Lorsque j'ai supprimé ApplicationEventListener de l'application et que j'ai simplement appelé une méthode publique sur le bean pour démarrer le service (au lieu de s'appuyer sur ApplicationEventListener), l'application a démarré normalement avec toutes les annotations @Scheduled fonctionnant comme prévu.

Questions connexes