Spring源码解析——4、bean的加载

Spring源码解析——4、bean的加载

  • bean的加载
    • 1、FactoryBean的使用
    • 2、缓存中获取单例bean
    • 3、从bean的实例中获取对象
    • 4、获取单例bean
    • 5、准备创建bean
        • 5.1 处理oveirrde属性
        • 5.2 实例化的前置处理
    • 6、循环依赖
        • 6.1 什么是循环依赖
        • 6.2 Spring如何解决循环依赖
    • 7、创建bean
        • 7.1创建bean的实例

bean的加载

对于加载bean的功能,spring中的调用方式为:
    ApplicationContext bf = new ClassPathXmlApplicationContext("spring/spring.xml");
    User user = (User) bf.getBean("testBean");
Spring加载bean的步骤:
	转换对应beanName
	尝试从缓存中加载单例
	bean的实例化
	原型模式的依赖检查
	检查ParentBeanFactory
	将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
	寻找依赖
	针对不同的scope进行bean的创建
	类型转换

1、FactoryBean的使用

一般情况下,spring通过反射机制利用bean的class属性指定实现类来实例化bean。

2、缓存中获取单例bean

从getSingleton方法中获取bean。
单例在spring的同一个容器只会被创建一次,后续在获取bean直接从单例缓存中获取。
  • singletonObjects:用于保存beanName和创建bean实例之间的关系;

  • singletonFactories:用于保存beanName和创建bean的工厂之间的关系;

  • earlySingletonObjects:也是保存beanName和创建bean实例之间的关系,与singletonFactories不同的是,当一个bean实例被放到这个里边之后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环依赖;

  • registeredSingletons:用来保存当前所有已注册的bean

3、从bean的实例中获取对象

从getObjectForBeanInstance方法中获取bean实例的步骤:
  • 对FactoryBean正确性的验证
  • 对非FactoryBean不做任何处理
  • 对bean进行转换
  • 将从Factory中解析bean的工作委托给getObjectFromFactoryBean方法

4、获取单例bean

从getSingleton方法中获取bean的步骤:
  • 检查缓存是否已经加载过
  • 若没有加载,则记录beanName的正在加载状态
  • 加载单例前记录加载状态
  • 通过调用参数传入的ObjectFactory的个体Object方法实例化bean
  • 加载单例后的处理方法调用
  • 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
  • 返回处理结果

5、准备创建bean

  • 通过ObjectFactory接口的方法getObject
  • 找到AbstrctBeanFactory中的doGetBean方法中的getSingleton方法
  • 找到createBean方法

createBean方法的步骤:

  • 根据设置的class属性或者根据className属性来解析class
  • 对oveirrde属性进行验证及标记
  • 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
  • 创建bean

5.1 处理oveirrde属性

在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrids属性里。

5.2 实例化的前置处理

Spring中的规则是在bean的初始化后尽可能将注册的后处理器的applyBeanPostProcessorsAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,则不会再经理bean的初始化创建过程。

6、循环依赖

6.1 什么是循环依赖

即循环引用

6.2 Spring如何解决循环依赖

在Spring中将循环依赖的处理分成了三种情况:
1、构造器循环依赖
表示通过构造器注入构成的循环依赖,此依赖事无法解决的
2、setter循环依赖
表示通过setter注入方式构成的循环依赖,只能解决单例作用域的bean循环依赖
3、prototype范围的依赖处理
对于‘prototype’作用域bean,Spring容器无法完成依赖注入,因为spring容器不进行缓存‘prototype’作用域的bean,因此无法提前暴露一个创建中的bean

7、创建bean

常规bean的创建就是在doCreateBean方法中完成的,步骤如下:
	1、如果是单例则需要先进行清除缓存
	2、实例化bean,将BeanDefinition转换为BeanWrapper
	3、MergedBeanDefinitionPostProcessor的应用,Autowire注解正是通过此方法实现诸	
	4、如类型的预解析
	5、依赖处理
	6、属性填充
	7、循环依赖检查
	8、注册DisposableBean,如果配置了destroy-method,这里需要注册以便于在销毁时来调用
	9、完成创建并返回

7.1创建bean的实例

reateBeanInstance方法

你可能感兴趣的:(Spring源码深度解析,Spring,spring源码,框架,Java)