springaopspring-aspects

spring autowired aop circular dependency


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.


Solution

  • AsyncConfigurer configuration classes get initialized early in the application context bootstrap. If you need any dependencies on other beans there, make sure to declare them @Lazy as far as possible in order to let them go through other post-processors as well.

    Reference JavaDoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html