源码解析-SpringIOC容器初始化,Bean实例化过程

本节重点分析Spring容器启动中 读取配置文件 解析一个个Bean封装成BeanDifinition注入到Map中 完成Bean的实例化过程(注意是实例化,并没有初始化)

本节的重点就是 看到下obtainFreshBeanFactory()这个过程中做的事  

 

源码分析

这一阶段先记住ApplicationContext一个重要的子类  - AbstractRefreshableApplicationContext

刷新工厂的操作有这货实现

还是从new ClassPathXmlApplicationContext()入口看一下

 源码解析-SpringIOC容器初始化,Bean实例化过程

 源码解析-SpringIOC容器初始化,Bean实例化过程

源码解析-SpringIOC容器初始化,Bean实例化过程

 源码解析-SpringIOC容器初始化,Bean实例化过程

来了obtainFreshBeanFactory();

 

1. obtainFreshBeanFactory()

 源码解析-SpringIOC容器初始化,Bean实例化过程

refreshBeanFactory();   // shutdown之前的工厂,开启一个新的工厂生命周期

beanFactory = getBeanFactory();   // 获取BeanFactory,也就是上一步刚创建的BeanFactory这个是在AbstractRefreshableApplicationContext中的

将这个beanFactory返回;

 

先看一下getBeanFactory()实现

源码解析-SpringIOC容器初始化,Bean实例化过程

先上了把锁,保证多线程串行获取

返回这个beanFactory,默认是DefaultListableBeanFactory

上节说过这个factory继承了上边全部Factory接口 也就是最叼的一个

 

2. refreshBeanFactory()  销毁旧工厂 开启并初始化新工厂

 源码解析-SpringIOC容器初始化,Bean实例化过程

if (是否有factory了){

       //如果有就销毁所有的bean 然后关闭factory

}

try{

       DefaultListableBeanFactory beanFactory = 创建BeanFactory();

       设置一个序列化id;

       customizeBeanFactory();    定制beanFactory;

       锁{

             把这个factory存下来

       }

 

}

 

3. createBeanFactory()  这个没啥好说的 就是new了一个DefaultListableBeanFactory()

然后设置一下parentBeanFactory,默认是null的

 源码解析-SpringIOC容器初始化,Bean实例化过程

 

4. cusomizeBeanFactory(beanFactory);  定制刚创建的beanFactory

源码解析-SpringIOC容器初始化,Bean实例化过程

是否允许bean被覆盖

是否允许bean循环依赖

 

5. loadBeanDefinitions 最重要的一步了,加载入bean的定义从XmlBeanDefinitionReader

源码解析-SpringIOC容器初始化,Bean实例化过程

new 了一个XmlBeanDefinitionReader,把当前这个beanFactory设置进去;

设置一些参数 姑且忽略;

 

initBeanDefinitionReader(); //初始化Bean定义阅读器

loadBeanDefinitions();       //加载  重点!!

 

6.loadBeanDefinitions(XmlBeanDefinitionReader )  最重点的加载来了

 源码解析-SpringIOC容器初始化,Bean实例化过程

 源码解析-SpringIOC容器初始化,Bean实例化过程

传入配置,for循环 每一个配置文件加载一次 记录count,继续往下

 源码解析-SpringIOC容器初始化,Bean实例化过程

重点了 从xml文件加载 bean definitions

源码解析-SpringIOC容器初始化,Bean实例化过程

Set  surrentResources = 将当前resource配置源加载到ThreadLocal这里

InputStream inputSream = 将配置源输入流获取到

获取inputSource并配置编码集

doLoadBeanDefinitions(inputSource)  真正干实事的在这

 源码解析-SpringIOC容器初始化,Bean实例化过程

从配置元将元素解析成Document树  //

处理了各种异常情况

return registerBeanDefinitions();   //注册成BeanDifinition

 

 

6. 元素注册成BeanDefinitions,返回注册前后的数量差

源码解析-SpringIOC容器初始化,Bean实例化过程

int countBefore = 注册之前的BeanDefinition的数量;

注册;

return 前后数量差;

 

7. 从DOM元素中读取bean definitions,通过reader context注册他们

源码解析-SpringIOC容器初始化,Bean实例化过程

获取根元素,开始注册

 源码解析-SpringIOC容器初始化,Bean实例化过程

根据根元素 注册每个bean definition

别的都忽略 重点看parseBeanDefinitions(root, this.delegate); 将元素解析成Bean

 源码解析-SpringIOC容器初始化,Bean实例化过程

// default namespace 涉及到的就四个标签 <import />、<alias />、<bean /> 和 <beans />,

// 其他的属于 custom 的

源码解析-SpringIOC容器初始化,Bean实例化过程

namespace就是xml文件中的这个东东,默认是beans

我们继续追下去

 源码解析-SpringIOC容器初始化,Bean实例化过程

 源码解析-SpringIOC容器初始化,Bean实例化过程

将配置文件中<bean>节点的信息提取出来,封装成一个beanDifinitionHolder

继续注册

 

 

8.BeanDefinitionReaderUtils.registerBeanDefinition()

源码解析-SpringIOC容器初始化,Bean实例化过程

String beanName = 通过definitionHolder获取bean的名称

根据beanName注册成BeanDefinition

 源码解析-SpringIOC容器初始化,Bean实例化过程

如果有别名,for循环别名 挨个注册

 

 

具体注册细节 未完待续、、、

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

上一篇:javax.persistence.spi.PersistenceUnitInfo.getSharedCacheMode()Ljavax/persistence/SharedCacheMode;


下一篇:【laravel】数据填充:报错,不保存时间戳