2015-03-11 2 views
14

Я использую конфигурацию java с @ComponentScan, чтобы инициализировать мои компоненты и @EnableAspectJAutoProxy(proxyTargetClass=true) для использования прокси cglib.spring autowired aop circle dependency

В этом проекте у нас есть много сгенерированных сервисов, проложенных между ними с использованием @Autowired. Это работает очень хорошо.

Но для некоторых из этих услуг я добавил @Async (я также добавил @EnableAsync(proxyTargetClass = true) на мой класс @Configuration).

После этого, я получаю:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'ConversationUserLocalService': Bean with name 'ConversationUserLocalService' has been injected into other beans [ConversationUserHistoryLocalService] i 
n its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'a 
llowEagerInit' flag turned off, for example. 

Я думаю, это потому, что весна инъекционная службы с @Async методом ДО АОП создает прокси-сервер. Это может быть проблема? Как я должен это исправить?

Для того, чтобы попытаться прояснить мою проблему, скажем, у меня есть:

@Service A, B & C

А имеет autowired B & C B имеет autowired A & C C имеет autowired A & B

C имеет метод, обозначенный как @Async.

Когда Spring инициализирует applicationContext, он пытается инициализировать A, но ему нужен B & C, поэтому он инициализирует их. Но, в конце концов, AOP пытается сделать прокси-сервер C (потому что @Async), а затем обнаруживает, что автоуровень C в B и A не совпадает с прокси-сервером C, поэтому он терпит неудачу.

Надеюсь, это может объяснить немного больше того, что происходит.

+0

Пожалуйста, пост [SSCCE] (http://sscce.org/) –

ответ

16

Наконец я разобрался с использованием @Lazy на услугах (с помощью методов, аннотированных @Async), а также , где они были autowired. Таким образом, я предполагаю, что Spring только инициализирует и автоматически выполняет эти службы, когда они необходимы, а не при инициализации контекста приложения.

+0

Эй, вы можете объясните со стороны: «он обнаруживает, что autowired C в B и A не совпадает с прокси-сервером C» –

+0

Когда Spring создает прокси для добавления асинхронного поведения в C, он не обновляет ссылки на A и B. Таким образом, оба они имеют ссылку на исходную версию C. – ilopezluna

+0

спасибо за объяснение. еще одна вещь, будет ли это зависеть от порядка, в котором весна инициализирует услуги. В вашем примере, если весна инициализирована сначала C, то тогда произойдет одно и то же исключение? –

0

мне удалось исправить подобную проблему путем добавления @Qualifier вместе с @Autowire, например:

@Autowired 
@Qualifier("publisher") 
private Publisher publisher; 
Смежные вопросы