spring autowired aop circular dependency

ilopezluna picture ilopezluna · Mar 11, 2015 · Viewed 21.4k times · Source

I'm using java config with @ComponentScanin order to initialize my beans and @EnableAspectJAutoProxy(proxyTargetClass=true)to use cglib proxies.

In this project we have a lots of generated services autowired between them using @Autowired. It works pretty well.

But, for some of these services I've added @Async (I've also added @EnableAsync(proxyTargetClass = true)on my @Configurationclass).

After that, I'm getting:

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.

I guess this is because Spring is injecting the service with @Asyncmethod BEFORE AOP creates the proxy. Could this be the problem? How I should fix it?

In order to try to clarify my problem, let's say I have:

@Service A, B & C;

A has autowired B & C, B has autowired A & C, C has autowired A & B;

C has a method marked as @Async.

When Spring initialize applicationContext, it tries to initialize A, but needs B & C, so it initializes them. But after all, AOP tries to make a proxy of C (because @Async) and then it detects that autowired C into B and A is not the same as proxy of C so it fails.

I hope this can explain a little more what is happening.

Answer

ilopezluna picture ilopezluna · Mar 11, 2015

Finally I sorted it out using @Lazyon services (with methods annotated with @Async), and also, where they were autowired. This way I guess Spring only initialize and autowires those services when they're required instead of on application context initialization.