J'essaie l'annotation @Scheduled du printemps 3. Voici ma configuration (app.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:context="http://www.springframework.org/schema/context"
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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
"
>
<context:component-scan base-package="destiny.web"/>
<context:annotation-config/>
// other beans
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
</beans>
Et voici ma classe de service:
@Service
public class ServiceImpl implements Service , Serializable
{
//other injections
@Override
@Transactional
public void timeConsumingJob()
{
try
{
Thread.sleep(10*1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
@Override
@Scheduled(cron="* * * * * ?")
public void secondly()
{
System.err.println("secondly : it is " + new Date());
}
}
Cela fonctionne bien lors du test dans mon eclispe + junit, lors du test d'une méthode timeConsumingJob, je peux voir que secondly () continue à émettre un message en second lieu.
Mais lorsqu'il est déployé dans un conteneur (Resin/4.0.13), il génère:
[11-03-26 12:10:14.834] {main} org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Only one AsyncAnnotationBeanPostProcessor may exist within the context.
Offending resource: class path resource [app.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.Java:68)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.Java:85)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.Java:72)
at org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser.parse(AnnotationDrivenBeanDefinitionParser.Java:82)
J'ai cherché mais je trouve rarement des situations similaires, je pense que c'est le paramètre le plus fondamental, mais je ne sais pas pourquoi cela ne fonctionne pas.
Quelqu'un peut-il jeter un coup d'oeil? Merci beaucoup !
(Spring 3.0.5, Resin 4.0.13)
------------ mis à jour ---------
Après avoir creusé plus profondément, j'ai découvert que le fichier app.xml est importé par un autre fichier XML. C’est peut-être pour cette raison que task:annotation-driven
ne fonctionne pas.
Eh bien, après avoir réorganisé l'emplacement de certains haricots, le problème est résolu, mais je me sens toujours perplexe. (Parce que cela a bien fonctionné et que other.xml a besoin de beans dans app.xml)
Le contexte d'application est en cours d'initialisation deux fois, mais org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser échoue lors de l'enregistrement du bean ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME.
J'ai rencontré ce problème dans des tests unitaires où @ContextConfiguration ("/ path/to/applicationContext.xml") était accidentellement sur la classe de test parent et la classe de test enfant (avec la valeur par défaut de inheritLocations true).
J'ai fait face à cela une fois après avoir implémenté notre propre AsyncTaskExecutor et oublié de supprimer le <task: annotation-driven/>
par défaut
Vérifiez si vous avez quelque chose comme ça, si oui, supprimez l'une des tâches.
<task:annotation-driven executor="customAsyncTaskExecutor" scheduler="taskScheduler"/>
<task:annotation-driven/>
Cela se produit lorsque spring analyse deux fois le texte <task:annotation-driven/>
dans un fichier XML de configuration.
Pour moi, cela se passait parce que applicationContext-root.xml
et applicationContext-where-annotation-driven-is-specififed.xml
ont été importés dans ma section WEB.xml
dans <context-param>
.
Ne laisser que applicationContext-root.xml
dans WEB.xml
a résolu le problème.
J'ai eu ce problème quand j'ai copié applicationContext.xml
et en ai créé un nouveau appelé applicationContextAdditional.xml
. Je n'ai pas essayé de trouver la raison, mais les deux contenaient un espace de noms
<bean ...
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.0.xsd" >
...
</bean>
quand j'ai enlevé le namespace du second, mon problème a été résolu. Peut-être que ça aide quelqu'un.
Dans mon cas, cela était dû au changement de version. Il existe donc plusieurs versions de fichiers JAR dans l'emplacement du fichier de sortie (chaque fichier JAR contient donc un AnnotationBean):
2018-02-19 13:38:44,913 [RMI TCP Connection(3)-127.0.0.1] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Only one ScheduledAnnotationBeanPostProcessor may exist within the context.
Offending resource: URL [jar:file:/C:/.../lib/xxx-2.0.jar!/META-INF/spring/xxx.xml]
pendant que j'utilise 1.0 dans ce cas. Je dois donc supprimer manuellement C:/.../lib/xxx-2.0.jar
à cet emplacement, et je peux voir que xxx-1.0.jar se trouve également dans ce répertoire. Après la suppression manuelle, cela fonctionne normalement.