IoC容器的实现学习——02目录
- IoC容器的实现学习——02
- 回顾
- IoC 容器的初始化过程:
- BeanDefinition 的 Resource 定位
- 小结:
- BeanDefinition 的 Resource 定位
具体实现的两种系列:BeanFactory 和 ApplicationContext
通过两种系列的具体 IoC 容器来帮助我们了解了两个不同的特点 , 以及面向不同的场景 。有利有弊,在开发中需要根据具体需求选择合适的 IoC 具体实现 。
其中也通过对 Spring IoC 的具体实现的简单分析,对 IoC 设计的有了初步的了解和想法 。那么现在就来开始了解 IoC 容器初始化的过程 。
IoC 容器的初始化过程:前面在学习 FileSystemXmlApplicationContext 的时候,构造方法中通过此类调用了
refresh()
方法 。IoC 容器的初始化实际上就是通过这个方法来启动的,标志着 IoC 容器正式启动 。IoC 容器的启动包括以下三个基本过程:
- BeanDefinition 资源的定位
- ~ 的载入
- ~ 的注册
lazyinit
的属性,用户可以通过这个属性改变 Bean 的依赖注入过程,eg:一般情况下 Bean 的注入需要在容器初始化之后,第一次调用 getBean()
时才会触发 , 而通过 lazyinit 属性可以让 Bean 在 IoC 容器初始化时就预先完成了依赖注入 。BeanDefinition 的 Resource 定位根据前面的学习 , 我们这一过程的表层应该不难知晓,就是通过定义一个 Resuorce 去定位容器使用的 BeanDefinition 。eg:
ClassPathResource()
这个类就是在项目中的类路径中寻找以文件形式存在的 BeanDefinition 。应该注意的是,不能把 Resource 的定位 BeanDefinition 资源和 BD 的载入弄混淆了 。只是定位资源而已,此时 IoC 容器还不能直接使用这些信息,这些信息是交由
BeanDefinitionReader
来对这些信息进行 BD 的载入处理 。相对于
DefaultListableBeanFactory
容器需要手动配置好特定的 Resource 读取器,ApplicationContext
容器就准备好了一系列的读取器 。但是使用
DefaultListableBeanFactory
这种底层容器可以根据业务定制 IoC 容器的灵活性,有利有弊 。还是通过
FileSystemXmlApplicationContext
这一具体容器来分析是如何完成 Resource 的定位过程 。继承体系:
文章插图
主要两个功能的源码:
文章插图
上图表明了
getResourceByPath()
是实现 Resource 定位的方法 。但是并不是使用者调用的,查看该方法的调用链:文章插图
上图标注了该方法最初是由
refresh()
方法触发的,而 refresh()
是在构造器中调用的 。我们需要通过这个方法来了解过程 。
构造器调用的是超类
AbstractApplicationContext
中的 refresh()
,查看源码:public void refresh() throws BeansException, IllegalStateException {synchronized(this.startupShutdownMonitor) {this.prepareRefresh();// 创建beanFactory以及扫描bean信息(beanDefinition) , 并通过BeanDefinitionRegistry 注册到容器中 。ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();// 省略...}}
obtainFreshBeanFactory()
源码:protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {this.refreshBeanFactory();// 省略...}
refreshBeanFactory()
是一个抽象方法,有两个具体的实现类:- AbstractRefreshableApplicationContext
- GenericApplicationContext
AbstractRefreshableApplicationContext
,所以我们看在这个类中 refreshBeanFactory()
的实现:protected final void refreshBeanFactory() throws BeansException {//...try {DefaultListableBeanFactory beanFactory = this.createBeanFactory(); // 1beanFactory.setSerializationId(this.getId());this.customizeBeanFactory(beanFactory);this.loadBeanDefinitions(beanFactory);// 2///...}}
我们抽出这两行代码进行分析:- 创建 BeanFactory,以 DefaultListableBeanFactory 作为 IoC 容器 。
- BD 的载入相关启动 。
推荐阅读
- Shell揭秘——程序退出状态码
- 基于PL022 SPI 控制器 海思3516系列芯片SPI速率慢问题深入分析与优化
- 六部恋爱甜甜电影推荐——冬天到了 一起恋爱吧 1. 这部电影也太好看了
- 0025:2011年NOIp普及组真题——瑞士轮题解
- 4 .NET 6学习笔记——如何在.NET 6的Desktop App中使用Windows Runtime API
- 学习ASP.NET Core Blazor编程系列八——数据校验
- 1 Redis—问题
- 之四 2流高手速成记:SpringBoot整合redis及mongodb
- 自己动手写线程池——向JDK线程池进发
- 微服务组件--限流框架Spring Cloud Hystrix分析