Spring循环依赖
@Service
class A{
@Autowired
B b;
}
@Service
class B{
@Autowired
A a;
}
public static void main(String[] args) {
Object bean = new ClassPathXmlApplicationContext().getBean("a");
}
首先从main函数进入获取bean,进入到AbstractBeanFactory # doGetBean()方法,
- singletonObjects:一级缓存 存储的是所有创建好了的单例Bean
- earlySingletonObjects:完成实例化,但是还未进行属性注入及初始化的对象
- singletonFactories:提前暴露的一个单例工厂,二级缓存中存储的就是从这个工厂中获取到的对象
进入到拉姆达表达式的createBean()方法:
在进入到doCreateBean()方法
PS:假如使用两个缓存就需要对象创建后(此时并没有注入属性)就需要创建该对象的代理对象,而Spring在设计之初就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来在Bean生命周期的最后一步来完成AOP代理。
假如没有循环依赖,代理对象一般在bean的后置处理器处理。而出现了循环依赖,没有办法,只能提前代理。
过程(没有代理对象生成时):
1.进入到populateBean()方法,发现有一个b属性,于是会调用getBean(),getBean调用doGetBean()即图一 方法。
2.去创建B对象,直到执行到populateBean(),此时B又依赖A,
3.又去加载A,进入到图一第一行的getSigton()方法(图二),从三级缓存中取出A并返回。
4.然后填充B类,B加载完后,接着填充A类。(类似一个递归去加载另一个对象)A,B加载完成。
过程(有代理对象生成时):
上面过程3,从三级缓存获取到A时,执行了拉姆达表达式既图六。提前生成代理对象。
SpringBean的生命周期
看到图五的初始化Bena方法
initializeBean():
然后Bean就可以使用了----使用完后销毁
DisposableBean 的destroy()方法和@PreDestroy和destroy-method的方法调用
实例化之前 ->InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
实例化
实例化之后 ->InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
填充属性
回调Aware相关接口
初始化之前 ->BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)
初始化 ->InitializingBean.afterPropertiesSet(),init-method,@PostConstruct
初始化后->BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
DisposableBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// 1
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
if (earlySingletonExposure) {
// 2
addSingletonFactory(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 3
Object exposedObject = bean;
// 4
populateBean(beanName, mbd, instanceWrapper);
// 5
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
if (earlySingletonExposure) {
// 6
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 7
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 8
...
}
}
}
return exposedObject;
}
- 1处,创建bean对象,此时,属性什么的全是null,可以理解为,只是new了,field还没设置
- 2处,添加到第三级缓存;加进去的,只是个factory,只有循环依赖的时候,才会发挥作用
- 3处,把原始bean,存到exposedObject
- 4处,填充属性;循环依赖情况下,A/B循环依赖。假设当前为A,那么此时填充A的属性的时候,会去:new B;填充B的field,发现field里有一个是A类型,然后就去getBean(“A”),然后走到第三级缓存,拿到了A的ObjectFactory,然后调用ObjectFactory,然后调用AOP的后置处理器类:getEarlyBeanReference,拿到代理后的bean(假设此处切面满足,要创建代理);
经过上面的步骤后,B里面,field已经填充ok,其中,且填充的field是代理后的A,这里命名为proxy A。B 继续其他的后续处理。B处理完成后,被填充到当前的origin A(原始A)的field中 - 5处,对A进行后置处理,此时调用aop后置处理器的,postProcessAfterInitialization;前面我们说了,此时不会再去调用wrapIfNecessary,所以这里直接返回原始A,即
origin A - 6处,去缓存里获取A,拿到的A,是proxy A
- 7处,我们梳理下: exposedObject:origin A bean:原始A earlySingletonReference:
proxy A 此时,下面这个条件是满足的,所以,exposedObject,最终被替换为proxy A: