Spring Bean的生命周期和循环依赖

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. 1处,创建bean对象,此时,属性什么的全是null,可以理解为,只是new了,field还没设置
  2. 2处,添加到第三级缓存;加进去的,只是个factory,只有循环依赖的时候,才会发挥作用
  3. 3处,把原始bean,存到exposedObject
  4. 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. 5处,对A进行后置处理,此时调用aop后置处理器的,postProcessAfterInitialization;前面我们说了,此时不会再去调用wrapIfNecessary,所以这里直接返回原始A,即
    origin A
  6. 6处,去缓存里获取A,拿到的A,是proxy A
  7. 7处,我们梳理下: exposedObject:origin A bean:原始A earlySingletonReference:
    proxy A 此时,下面这个条件是满足的,所以,exposedObject,最终被替换为proxy A:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值