Affects: Spring Framework < 5.3.1
There are @Async and @Transactional annotations in the same class, and the class depends on itself. There will be a problem org.springframework.beans.factory.BeanCurrentlyInCreationException
example:
I think it is caused by the following code:
in AbstractAdvisingBeanPostProcessor
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
// I think there is a problem here, there is a problem with this judgment
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
// No proxy needed.
return bean;
}
My solution is as follows:
in AbstractBeanFactoryAwareAdvisingPostProcessor
@Nullable
protected ConfigurableListableBeanFactory beanFactory;
in AbstractAdvisingBeanPostProcessor
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if (isEligible(bean, beanName)) {
// The changes are as follows
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) this.beanFactory;
Object singleton = defaultListableBeanFactory.getSingleton(beanName);
if (singleton instanceof Advised) {
Advised advised = (Advised) singleton;
if (!advised.isFrozen()) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
} else {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
}
// No proxy needed.
return bean;
}
Comment From: snicoll
This is to be expected, you literally have a circular dependency in that screenshot. If you need to inject a bean in a bean itself, please use ObjectProvider
or @Lazy
to defer the resolution of the bean instance.