Подтвердить что ты не робот

Spring @Исправлена ​​ошибка: только один AsyncAnnotationBeanPostProcessor может существовать в контексте

Я пытаюсь аннотировать 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, я вижу, что secondly() продолжает выводить сообщение во-вторых.

Но при развертывании в контейнере (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 не работает.

Хорошо, после повторного размещения некоторого местоположения beans, он решен, но я все еще чувствую себя озадаченным. (Потому что он работал нормально, а other.xml нуждается в beans в app.xml)

4b9b3361

Ответ 1

Контекст приложения инициализируется дважды, но org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser не выполняет регистрацию bean ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME второй раз.

Я столкнулся с этой проблемой в модульных тестах, где @ContextConfiguration ( "/path/to/applicationContext.xml" ) случайно попал как в родительский тестовый класс, так и в класс дочерних тестов (со значением по умолчанию inheritLocations true).

Ответ 2

Я столкнулся с этим однажды после реализации нашего собственного AsyncTaskExecutor и забыл удалить по умолчанию <task: annotation-driven/>

Проверьте, есть ли у вас что-то подобное, если да, удалите одну из задач.

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

<task:annotation-driven/>

Ответ 3

Это происходит, когда spring дважды анализирует текст <task:annotation-driven/> в XML файле конфигурации.

Для меня это происходило, потому что оба applicationContext-root.xml и applicationContext-where-annotation-driven-is-specififed.xml были импортированы в разделе WEB.xml в <context-param>.

Оставляя только applicationContext-root.xml в WEB.xml, решила проблему.

Ответ 4

У меня была эта проблема, когда я скопировал 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>

когда я удалил пространство имен из второго, моя проблема была решена. Может быть, это помогает кому-то.

Ответ 5

В моем случае это было вызвано переключением версий, поэтому в расположении выходного файла есть несколько версий 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 также находится в этом каталоге. После ручного удаления работает нормально.

Ответ 6

У меня был <task:annotation-driven/> определенный дважды в контексте xml. Удаление это сработало для меня.