Spring автоматическая циркулярная зависимость

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

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

Я предполагаю, что это потому, что Spring вводит службу с помощью метода @Async ПЕРЕД AOP создает прокси. Это может быть проблема? Как я должен это исправить?

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

@Service A, B и C

A имеет автообновленные B и C B имеет автоподвод A и C C имеет автоуровневые A и B

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

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

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

Ответы

Ответ 1

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

Ответ 2

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

@Autowired
@Qualifier("publisher")
private Publisher publisher;

Ответ 3

Классы конфигурации AsyncConfigurer инициализируются на ранних этапах начальной загрузки контекста приложения. Если вам нужны какие-либо зависимости от других bean-компонентов, убедитесь, что они объявлены как "ленивые", насколько это возможно, чтобы позволить им проходить и через другие постпроцессоры.

Ссылка на JavaDoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html