Spring IoC容器源码分析

这篇文章是阅读《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中

3.准备 Bean 容器
prepareBeanFactory() 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean

4.初始化所有的 singleton beans(lazy-init 的除外)
finishBeanFactoryInitialization()->preInstantiateSingletons()->getBean()->createBean()->doCreateBean()->
createBeanInstance() 创建 Bean 实例
populateBean() bean 属性注入
initializeBean() BeanPostProcessor 的两个回调都发生在这边,只不过中间处理了 init-method

Note

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

  • BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。

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

猜你喜欢

转载自blog.csdn.net/sinat_34341162/article/details/84580854