Spring的@Scheduled错误:上下文中只能存在一个AsyncAnnotationBeanPostProcessor

时间:2011-03-26 05:11:53

标签: spring scheduler spring-3 crontrigger

我正在尝试Spring 3的@Scheduled注释。这是我的配置(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>

这是我的服务类:

@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());
  }
}

在我的eclispe + junit中测试时工作正常,在测试timeConsumingJob方法时,我可以看到其次继续输出消息。

但是当部署到容器(Resin / 4.0.13)时,它会抛出:

[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)

我搜索但很少发现类似的情况,我认为这是最基本的设置,但不知道它为什么不起作用。

有人可以看一下吗?非常感谢!

(Spring 3.0.5,Resin 4.0.13)

------------ 已更新 ---------

在深入挖掘之后,我发现app.xml是由另一个xml导入的。也许这就是使task:annotation-driven无效的原因。

好吧,重新安排一些豆子的位置后,它就解决了,但我仍然感到困惑。 (因为它工作正常,而other.xml需要app.xml中的bean)

7 个答案:

答案 0 :(得分:15)

应用程序上下文正在初始化两次,但org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser第二次无法注册bean ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME。

我在单元测试中遇到了这个问题,其中@ContextConfiguration(“/ path / to / applicationContext.xml”)意外地出现在父测试类和子测试类上(默认值为inheritLocations为true)。

答案 1 :(得分:8)

在实现我们自己的AsyncTaskExecutor并忘记删除默认<task: annotation-driven/>

后,我遇到过这个问题

检查是否有这样的东西,如果是,则删除其中一项任务。

<task:annotation-driven executor="customAsyncTaskExecutor" scheduler="taskScheduler"/>

<task:annotation-driven/>

答案 2 :(得分:7)

当spring在配置XML中解析<task:annotation-driven/>文本两次时会发生这种情况。

对我而言,这种情况正在发生,因为applicationContext-root.xmlapplicationContext-where-annotation-driven-is-specififed.xml都导入WEB.xml部分的<context-param>

仅在applicationContext-root.xml中留下WEB.xml解决了这个问题。

答案 3 :(得分:6)

当我复制applicationContext.xml并创建一个名为applicationContextAdditional.xml的新问题时,我遇到了这个问题。我没有尝试找到原因,但都包含名称空间

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

当我从第二个删除命名空间时,我的问题解决了。也许它有助于某人。

答案 4 :(得分:0)

在我的情况下,这是由切换版本引起的,因此在输出文件位置有多个版本的jar(因此每个jar包含一个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]

虽然我在这种情况下使用1.0。所以我必须在这个位置手动删除C:/.../lib/xxx-2.0.jar,我能够看到xxx-1.0.jar也在这个目录中。手动删除后,它正常工作。

答案 5 :(得分:0)

大约

的错误
Only one AsyncAnnotationBeanPostProcessor may exist within the context

,可能还会出现另一种情况。我并不坚持认为那必须对您有所帮助,也许您确实遇到了其他帖子中描述的一些复杂问题,但是没有人帮助我。

有什么帮助,很简单

mvn clean

,因为该项目以某种方式创建了一些重复的文件,这些文件导致了问题。一个简单的清洁程序...嗯...清洗了它们。

例如,这种情况可能发生在与具有更高版本项目的分支合并之后。

答案 6 :(得分:-1)

我在上下文xml中两次定义了<task:annotation-driven/>。删除对我有用的。