图解spring的bean创建的生命周期

DefaultListableBeanFactory AbstractAutowireCapableBeanFactory InstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessor AutowiredAnnotationBeanPostProcessor BeanPostProcessor 根据名字获取bean,如果单例beanMap中有已经有该bean直接返回 创建bean 根据name创建bean 实例化bean之前 给个机会后置处理器对对应的(class)的beanName进行实例化, 返回已经实例化的bean,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 返回后置处理器处理完的bean实例化对象 loop [遍历所有的InstantiationAwareBeanPostProcessor接口实现类的后置处理器] 如果处理结果为null直接跳过, 否则认为bean已经实例化成功, 容器不会对bean进行属性填充了和初始化了, 直接调用bean的后置处理器的方法applyBeanPostProcessorsAfterInitialization(bean, beanName) 常规创建bean。 doCreateBean(beanName, mbdToUse, args) 调用构造方法实例化bean 确定一个构造方法实例化bean,instantiateBean(beanName, mbd) 实例化bean完成 当前bean是否允许依赖- 循环, 提前暴露bean的Obje- ctFactory引用 获取对指定bean的早期访问的引用, 通常用于解析循环引用。getEarlyBeanReference(Object bean, String beanName) 把getEarlyBeanReference返回的设置到ObjectFactory三级缓存里面 loop [:遍历所有实现SmartInstantiationAwareBeanPostProcessor接口 后置处理器] 实例化bean完成 填充bean属性,这里会自动注入依赖的bean 获取bean定义的所有属性值 遍历所有的InstantiationAwareBeanPostProcessor接口实现类的后置处理器 给个机会后置处理器返回填充bean属性的值, postProcessProperties(pvs, bw.getWrappedInstance(), beanName),也可以自己填充bean的属性 填充完注解依赖注入的属性 初始化bean。 initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) 注入bean的各种Aware 给个机会后置处理器替换当前的bean,该bean已经填充完属性, 不会对bean再进行填充,postProcessBeforeInitialization(result, beanName) loop [:遍历所有的BeanPostProcessor接口实现类的后置处理器] 初始化bean,调用用户自定义初始化方法, 如果bean实现了InitializingBean,调用afterPropertiesSet方法 给个机会后置处理返回一个bean替换当前的bean, 当前bean已经填充完成属性,一般返回代理类的实现 loop [:遍历所有BeanPostProcessor后置处理器] 创建bean完成 DefaultListableBeanFactory AbstractAutowireCapableBeanFactory InstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessor AutowiredAnnotationBeanPostProcessor BeanPostProcessor bean的生命周期

注意:

  • 实例化是使用class实例化和初始化是实例化之后进行的,博主一直把这个搞混了。所以如果使用后置处理器自定义实例化后spring生命周期直接跳过属性填充这个步骤,表明实例化完成
  • spring的aop是属性填充完成之后这一步返回一个代理对象替换原先的bean实现的。
  • 实例化之后,spring会提前暴露当前的bean引用对象到三级缓存里面,这样可以解决依赖循环问题

spring的三级缓存分类如下:

名称描述
singletonObjects一级缓存,存放完整的 Bean。
earlySingletonObjects二级缓存,存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 init 方法。
singletonFactories三级缓存,存放的是 Bean 工厂,主要是生产 Bean,存放到二级缓存中。
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {   
		    //如果当前一级缓存里面beanName
			if (!this.singletonObjects.containsKey(beanName)) {    
			    //加入三级缓存
				this.singletonFactories.put(beanName, singletonFactory);
				//清除二级缓存
				this.earlySingletonObjects.remove(beanName);
				
				this.registeredSingletons.add(beanName);
			}
		}
	}

依赖注入的时候获取bean对象

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  // 一级缓存
  Object singletonObject = this.singletonObjects.get(beanName);
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
      // 二级缓存
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
        // 三级缓存
        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
        if (singletonFactory != null) {
          // Bean 工厂中获取 Bean
          singletonObject = singletonFactory.getObject();
          // 放入到二级缓存中
          this.earlySingletonObjects.put(beanName, singletonObject);
          //清除二级缓存对象
          this.singletonFactories.remove(beanName);
        }
      }
    }
  }
  return singletonObject;
}

备注:

  • 一级缓存,这个就是不用重复创建单例对象
  • 二级缓存防止产生多个代理对象,否则一级缓存和三级缓存就够了。假如依赖循环中,后面有多个属性依赖A的Bean,没有二级缓存就会创建多个。
  • 第三级缓存的目的是为了延迟代理对象的创建,因为如果没有依赖循环的话,那么就不需要为其提前创建代理,可以将它延迟到初始化完成之后再创建。
    -如果使用二级缓存实现,如果 Spring 选择二级缓存来解决循环依赖的话,那么就意味着所有 Bean 都需要在实例化完成之后就立马为其创建代理,而 Spring 的设计原则是在 Bean 初始化完成之后才为其创建代理。所以,Spring 选择了三级缓存。但是因为循环依赖的出现,导致了 Spring 不得不提前去创建代理,因为如果不提前创建代理对象,那么注入的就是原始对象,这样就会产生错误。

参考https://www.jb51.net/article/197450.htm

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值