Spring IoC容器源码分析

这篇文章是阅读《Spring技术内幕》和《SpringIoC容器源码分析》后的个人笔记。

Spring 是渐进式的工具,并不具有很强的侵入性,它的模块也划分得很合理,即使你的应用不是 web 应用,或者之前完全没有使用到 Spring,而你就想用 Spring 的依赖注入这个功能,其实完全是可以的,它的引入不会对其他的组件产生冲突。

启动过程分析

ClassPathXmlApplicationContext 的构造方法中的核心方法refresh()。

之所以方法名是refresh,是因为ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建的,refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。

refresh()调用的一些方法

1.准备工作
prepareRefresh():记录启动时间、校验配置文件等。

2.初始化 BeanFactory、加载 Bean、注册 Bean
obtainFreshBeanFactory()->
refreshBeanFactory()->
createBeanFactory()
customizeBeanFactory() 配置是否允许 BeanDefinition 覆盖、是否允许循环引用。
loadBeanDefinitions()->loadBeanDefinitions(beanDefinitionReader) 加载配置->doRegisterBeanDefinitions() 解析 Bean 定义->parseBeanDefinitions()->
parseDefaultElement()->processBeanDefinition() 解析 bean 标签->
parseBeanDefinitionElement()->parseBeanDefinitionElement() 根据配置创建 BeanDefinition 实例,转换为 BeanDefinitionHolder
registerBeanDefinition()->registerBeanDefinition()将 BeanDefinition 放到beanDefinitionMap中

  • Resource定位:指的是BeanDefinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成。
  • BeanDefinition的载入:把用户定义好的Bean表示成IoC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。
  • BeanDefinition的注册:通过调用BeanDefinitionRegistry接口的实现来完成的。这个注册过程是把载入过程中解析得到的BeanDefinition向IoC容器进行注册。

Note
这里的 BeanDefinition 就是我们所说的 Spring 的 Bean,我们自己定义的各个 Bean 其实会转换成一个个 BeanDefinition 存在于 Spring 的 BeanFactory 中。
到这里已经初始化了 Bean 容器, 配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到注册中心,并且发送了注册事件。

3.准备 Bean 容器
prepareBeanFactory() 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,Spring 在把我们在 xml 配置的 bean 都注册以后,手动注册几个特殊的 bean,如environment,systemProperties等。

4.初始化所有的 singleton beans(lazy-init 的除外)
单例的、没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。

finishBeanFactoryInitialization()->preInstantiateSingletons()->getBean()
已经初始化过了就从容器中直接返回,否则就先初始化再返回。

->createBean()->doCreateBean()->
createBeanInstance() 创建 Bean 实例
populateBean() bean 属性注入
initializeBean() BeanPostProcessor 的两个回调都发生在这边,只不过中间处理了 init-method

Note

  • ApplicationContext 继承自 BeanFactory,
    但是它不应该被理解为 BeanFactory 的实现类,
    而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)。

  • Bean 在代码层面上可以认为是 BeanDefinition 的实例。BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。

  • depends-on:用来确定bean定义中依赖关系不明确或者没有直接依赖关系时,指定bean在初始化或销毁时的明确顺序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值