spring之bean的生命周期相关

Spring 之bean的生命周期

1、什么是循环依赖?

	所谓循环依赖就是对象A依赖对象B,对象B又依赖对象A。通过<property>注入的方式可以解决。

但是如果是通过构造器方式注入循环依赖的bean就不可以,因为是在实例化A之前去解析循环依赖的B

2、容器getBean()流程

@Autowired
	ApplicationContext act;
	@Test
	void contextLoads() {
		Object helloService = act.getBean("helloService");

我们通过断点application最顶层接口的getBean方法,来分析从容器中获取一个bean的流程。

  1. org.springframework.context.support.AbstractApplicationContext#getBean-------->getFactory().getBean()

  2. org.springframework.beans.factory.support.AbstractBeanFactory#getBean

  3. org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    3.1 transformedBeanName 解析别名和去掉beanFactory的前缀标识符‘&’从而得到真正的beanname;

    3.2 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton------>去单例注册器中的缓存中获取已经注册的单例bean,(由于 第一次创建,缓存池中没有对象,返回为null);

    3.3 org.springframework.beans.factory.support.AbstractBeanFactory#isPrototypeCurrentlyInCreation判断beanFactory中的原型循环依赖队列中是否包含这个bean,也就是判断这个bean是不是循环依赖的原型bean,如果是,直接抛出异常;

    3.4 判断当前容器是否存在父工厂,如果存在尝试去父工厂获取bean;

    3.5 父工厂不存在,合并beanDefinition, 根据其属性stale来判断这个bean定义是否需要合并;

    3.6 合并之后,检查当前的beanDefiniton是否是抽象的,如果抽象的直接抛出异常;

    3.7 作dependsOn的依赖检查 @DependsOn

    3.8 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(重载函数,入参一个objectFactory和上面的从各级缓存中获取bean不一样)

    ​ 3.8.1 singletionObjects缓存获取bean, 第一次没有

    ​ 3.8.2 beforeSingletonCreation(),将beanName加入singletonsCurrentlyInCreation队列,来标识这个bean正在创建,这个是以后判断是否需要提前暴露bean的判断条件

    ​ 3.8.3 调用 singletonFactory.getObject(),从而调用ObejctFactory的createBean()来创建bean.

  4. 创建bean的流程---->beans.factory.support.AbstractAutowireCapableBeanFactory#createBean。

    4.1 resolveBeforeInstantiation(beanName, mbdToUse) 该方法实现了aop的切面功能,返回一个代理对象。(原理一会儿看);

    4.2 doCreateBean(),该方法是真正来创建bean的.

  5. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

    5.1 createBeanInstance()---->调用构造器去创建bean实例----->instantiateBean()

    5.2 instantiateBean() —> 生成包装bean BeanWrapper. 具体生成是通过org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate ,通过beanDefinition的bean class,获取构造器,然后通过BeanUtils.instantiateClass(constructorToUse)反射生成bean实例(construtor.newInstance())。

    5.3 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 执行符合bean定义相关的后置处理器,这里注意,我们@autowire 方式注入的其它bean,会通过AutowiredAnnotationBeanPostProcessor 这个后置处理器,解析@autowire注解下面的元数据,将它放到bean定义中的 externallyManagedConfigMembers中,标识这个bean 需要注入它。这里的bean属性还未复制,也就是spring 里面所称的早期暴露对象。

    5.4 上一步我们获取了早期对象,但是我们还要把这个对象暴露给其它可能引用它的bean,addSingletonFactory()------->我们就需要把它包装成ObjectFactory(具体类型:abstractAutowireCapableBeanFactory)的形式放到beanFactory的三级缓存(beanFactroies)中

  6. bean初始化完成,开始bean的属性赋值过程,也是bean生命周期的第二大步骤;org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

    6.1 hasInstantiationAwareBeanPostProcessors()来判断beanFactory是否含有实例化beanAware后置处理器,如果有遍历执行。

    6.2 获取需要自动注入的属性 用@autowire 标注的属性用mbd.getPropertyValues()是获取不到的

    6.3 获取bean定义中的自动注入类型,type name constructor, 根据不同的自动注入类型注入上一步获取的需要注入的属性值。

    6.4 上面自动注入的属性是通过xml配置的,而我们通过@resouce(CommonAnnotationBeanPostProcessor) 和@autowire和@value (AutowiredAnnotationBeanPostProcessor)注入的属性,是通过遍历beanFactory中的beanPostProcessors(), 如果属于InstantiationAwareBeanPostProcesser,则指定它的postProcessProperties()回调函数,从而注入我们通过注解标注的属性值。 具体通过 findAutowringMetadata()找到bean class里面被注解标注的属性,并返回包装为InjectionMetadata类型,在调用InjectionMetadata.inject()------->DefaultListAbleBeanFactory.doResolveDependency()-------->DependencyDescriptor.resolveCandidate()------->beanFactory.getBean()可以看到在注入这个bean的时候,最后还是返回到getBean()------->到了getBean(“B”)相当于我们又走了一遍上面的流程,而B依赖了前面我们创建的A, 同样在属性注入的环节它回去调用getBean(“A”), 而前面我们已经将A提前暴露了,所以这时候B可以获取到提前暴露的A,---------然后通过调用field.set(bean,value)将提前暴露的A注入到B中。

    6.5 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues()方法为bean属性进行赋值,这里会处理通过xml配置</>注入的bean

    6.6 调用 initializeBean(),对bean进行了初始化(细节一会儿看)

    6.7 调用org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton,将初始化好的bean放到单例缓存池中,并移除二级缓存,并将该bean加入到registeredSingletons中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值