Круговая зависимость

Я использую Java-конфиг с @ComponentScanдля того, чтобы инициализировать мои бобы и @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Метод ДО АОП создает прокси. Это может быть проблемой? Как мне это исправить?

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

@ Сервис 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, поэтому он терпит неудачу.

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

2 ответа

Решение

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

У меня такая же проблема, и я решил эту проблему:

  1. Я определил, какие @Autowired свойство является причиной круговой зависимости.

    Например:

    @Autowired
    private TestService testService;
    

    (Подсказки для выявления просто попробуйте прокомментировать и выяснить, какое свойство является причиной поломки приложения)

  2. После определения просто используйте @Lazy на вершине этого @Autowired переменная.

    Например:

    @Lazy
    @Autowired
    private TestService testService;
    

    И приложение работало без сбоев.

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

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

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

@Autowired
@Qualifier("publisher")
private Publisher publisher;
Другие вопросы по тегам