web-dev-qa-db-fra.com

printemps autowired aop circulaire dépendance

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 @Configurationclass).

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 @Asyncmethod 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.

18
ilopezluna

Enfin, j'ai trié le problème en utilisant les services @Lazyon (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.

26
ilopezluna

J'ai réussi à résoudre un problème similaire en ajoutant @Qualifier avec @Autowire, par exemple:

@Autowired
@Qualifier("publisher")
private Publisher publisher;
0
Joel Mata