1.spring可以通过二级缓存和三级缓存解决 循环依赖的问题
二级缓存:earlySingletonObjects
三级缓存:singletonFactories
BeanDefinition 通过构造方法生成原始对象(没依赖注入的对象),接着会执行下面的代码
//将原始对象加入三级缓存并且通过执行lambda表达式获取,执行lambda可能生成的代理对象,并且放入二级缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
通过构造方法注入会循环依赖,因为还没由生成原始对象,放入三级缓存中,
例如:
@Component
public class A{
@Autowired
private B b;
}
@Component
public class B{
public B(A a){
}
}
如果先执行的A,会放入原始A对象到3级缓存,这种不会循环依赖 如果先执行的B,会在构造注入阶段,发现需要A对象,去找A,但是发现A也需要注入B,这时候在3级缓存中没有发现B的原始对象存在,产生循环依赖问题
2.@Bean 默认的autowireMode=3
如果添加了autowire = Autowire.BY_TYPE后就会变成2
//int AUTOWIRE_BY_NAME = 1;
//int AUTOWIRE_BY_TYPE = 2;
@Component
public class User {
}
@Bean(autowire = Autowire.BY_TYPE)
public User1 user1( User user){
return new User1();
}
//这里设置
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
后面去执行当前user1(User user)方法的时候会判断
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
//这里会报错 所以@Bean上面别加autowire = Autowire.BY_TYPE 或者autowire = Autowire.BY_NAME
@Bean
public User1 user1( User user){
return new User1();
}
这样就不会报错