前言
参考资料:《Spring技术内幕:深入解析Spring架构与设计原理(第二版)》
IoC容器是Spring框架的核心。这篇文章总结Spring IoC容器 BeanFactory的启动流程,作一个本阶段知识总结。
关于IoC容器
简介
IOC容器为开发者管理对象间的依赖关系提供了便利。主要有两种容器:
-
实现BeanFactory接口的简单容器,只实现了基本功能。ConfigurableBeanFactory。
-
ApplicationContext接口应用上下文,容器的高级形态,继承了BeanFactory。ConfigurableApplicationContext。
生命周期
IoC容器的生命周期
- 容器初始化
- 依赖注入
- 关闭过程
下面分别对这几个过程进行分别说明:
初始化过程
定义:BeanDefinition用来对一个bean进行描述,包括属性和构造方法等
IoC容器接口的refrash()方法进行初始化。
大体流程如下:
-
Resource定位过程。指的是BeanDefinition的资源定位。通俗来说,解析配置文件
-
BeanDefinition的载入和解析。通俗来说,将配置文件里解析的bean信息构建成BeanDefinition
-
向IoC容器注册这些BeanDefinition的过程。实际上是把BeanDefinition注入到一个HashMap中去,IoC容器就是通过这个HashMap来持有这些BeanDefinition数据的
-
完成初始化前的相关设置。包括:执行postProcessBeanFactory、注册BeanPostProcess、初始化国际化信息、注册监听事件等。
-
实例化设置非延迟初始化的bean
-
结束初始化
依赖注入
指IoC容器对Bean的依赖关系进行注入
doGetBean()方法是触发依赖注入的。
依赖注入过程图:
实例化方式
-
工厂方法
-
构造函数
-
jdk动态代理(基于JVM反射,只能代理接口)、CGLIB(基于修改字节码,可以代理接口和普通对象)。spring里代理类如果实现了接口用jdk动态代理,代理类没有实现任何接口用cglib
何时触发
IoC容器的依赖注入触发和标签中的lazy-init(预实例化)属性有关,默认lazy
-
lazy-init = true 用户第一次向IoC容器索要Bean的时候触发(例如:调用IoC容器getBean()方法)
-
lazy-init = false,Spring启动时容器初始化阶段被实例化
-
如果有两个类B依赖于A,A设置了lazy-init = true,B设置了lazy-init = false,那么A也会被提前实例化
关闭
doClose()方法关闭IoC容器
Bean的生命周期
Spring里的Bean的生命周期如下:
- Bean实例的创建
- 为Bean实例设置属性
- 调用Bean的初始化方法
- 应用可以通过IoC容器使用Bean
- 当容器关闭时,调用Bean的销毁方法
感悟
学习的过程是一个不断摸索的过程,刚开始我看《Spring技术内幕》可以说和啃天书没什么区别,简单看了一遍以后,过了一段时间的积累后,学习了一些设计模式和别的知识,今天回过头来看这本书,原来理解起来挺容易的。
而且也真的能运用起来(比如:自定义springboot-starter需要根据配置文件或者扫描自定义注解,动态注入bean,就可以从BeanFactory的初始化中Bean的注册过程入手)。