J'utilise Java config avec @ComponentScan
afin d'initialiser mes beans Et @EnableAspectJAutoProxy(proxyTargetClass=true)
pour utiliser les proxies cglib.
Dans ce projet, nous avons un grand nombre de services générés auto-câblés entre eux en utilisant @Autowired
. Ça marche plutôt bien.
Mais, pour certains de ces services, j’ai ajouté @Async
(j’ai également ajouté @EnableAsync(proxyTargetClass = true)
sur ma @Configuration
class).
Après cela, je reçois:
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.
Je suppose que cela est dû au fait que Spring injecte le service avec @Async
method AVANT que AOP crée le proxy .Cela pourrait être le problème? Comment résoudre ce problème?
Pour essayer de clarifier mon problème, disons que j'ai:
@Service A, B & C
A a auto-câblé B & C B a auto-câblé A & C C a auto-câblé A & B
C a une méthode marquée comme @Async.
Lorsque Spring initialise applicationContext, il essaie d'initialiser A mais a besoin de B & C pour les initialiser. Mais après tout, AOP essaie de créer un proxy de C (car @Async), puis détecte que C auto-câblé en B et A n’est pas identique au proxy de C et qu’il échoue.
J'espère que cela peut expliquer un peu plus ce qui se passe.
Enfin, j'ai trié le problème en utilisant les services @Lazy
on (avec les méthodes annotées avec @Async
), et aussi , où ils étaient auto-câblés . De cette façon, je suppose que Spring initialise et auto-pilote ces services uniquement lorsqu'ils sont requis initialisation du contexte d'application.
J'ai réussi à résoudre un problème similaire en ajoutant @Qualifier avec @Autowire, par exemple:
@Autowired
@Qualifier("publisher")
private Publisher publisher;