2015-03-11 16 views
14

Sto utilizzando java config con @ComponentScan per inizializzare i miei bean e @EnableAspectJAutoProxy(proxyTargetClass=true) per utilizzare i proxy cglib.molla autowired aop dipendenza circolare

In questo progetto sono disponibili molti servizi generati tra loro utilizzando @Autowired. Funziona piuttosto bene.

Ma, per alcuni di questi servizi ho aggiunto @Async (Ho anche aggiunto @EnableAsync(proxyTargetClass = true) sulla mia classe @Configuration).

Dopo di che, mi sto:

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. 

Credo che questo è perché la primavera sta iniettando il servizio con @Async metodo prima AOP crea il proxy. Questo potrebbe essere il problema? Come dovrei risolvere il problema?

Al fine di cercare di chiarire il mio problema, diciamo che ho:

@Service A, B & C

A ha autowired B & C B ha autowired A & C C ha autowired A & B

C ha un metodo contrassegnato come @Async.

Quando Spring inizializza applicationContext, tenta di inizializzare A, ma richiede B & C, quindi li inizializza. Ma dopo tutto, AOP prova a creare un proxy di C (perché @Async) e poi rileva che C autowired in B e A non è lo stesso di proxy di C, quindi fallisce.

Spero che questo possa spiegare un po 'di più cosa sta succedendo.

+0

Si prega di inviare un [SSCCE] (http://sscce.org/) –

risposta

16

Infine ho risolto fuori usando @Lazy sui servizi (con i metodi annotati con @Async), e anche, dove sono stati autowired. In questo modo, suppongo che Spring inizializzi e autorizzi solo quei servizi quando sono richiesti invece dell'inizializzazione del contesto dell'applicazione.

+0

Ehi, si può spiega da parte: "rileva che C autowired in B e A non è uguale al proxy di C" –

+0

Quando Spring crea un proxy per aggiungere un comportamento asincrono in C non aggiorna i riferimenti su A e B. Quindi entrambi loro hanno un riferimento alla versione originale di C. – ilopezluna

+0

grazie per la spiegazione. solo un'altra cosa, dipenderà dall'ordine in cui la molla inizializza i servizi. Nel tuo esempio, se la molla ha inizializzato C per primo, allora si verificherà la stessa eccezione? –

0

sono riuscito a risolvere un problema simile con l'aggiunta di @Qualifier insieme @Autowire, ad esempio:

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