共计 3602 个字符,预计需要花费 10 分钟才能阅读完成。
总概
最近始终在思考 Spring 的设计,从这个角度去思考这个框架,并且散发思考其余 Spring 的生态。而 Spring 的根底就是 Bean 的生命周期的治理,由此去合并 AOP 的性能,同时还有配置的治理,事件监听的治理,还有 MessageSource 的治理,还有资源的治理,等等散发开来。咱们先从 Spring 的 Bean 的生命周期这个角度去思考 Spring 的设计。
Spring 容器生命周期
咱们在思考 Spring 的 Bean 的生命周期之前须要站在更上一层,Spring 的容器生命周期去思考能力有一个残缺的大局观。说到这个大局观,咱们须要对 Spring 的容器的接口定义须要相熟一下,同时也须要相熟一下接口的实现的骨架,最初面去关注外围的几点,汇集了解 Spring 的 Bean 生命周期。
Bean 的生命周期咱们须要从这个角度去思考,首先咱们须要将 Bean 进行配置化,能够通过配置去批改 Bean 的值,所以咱们须要构建好 Environment。之后咱们须要把 Bean 的定义依照规定发现扫描,而后存储起来供前期实例化 Bean 应用。最初咱们开始 Bean 的生命周期的流转,而对于一个框架来说须要对每一步能够提供能够拓展的接口,包含实例化前后,初始化前后,以此能够更好拓展 Bean 的治理,以及能够供第三方接入 Bean 治理。
Spring 的容器接口
咱们这里做一些简略的介绍。首先是和咱们生产应用相干的是
web 相干接口:ConfigurableWebApplicationContext 和 WebApplicationContext。
外围接口:
- EnvironmentCapable:提供获取 Environment 接口
ListableBeanFactory/BeanFactory:提供 Bean 依赖查找。
至于其余的接口不是咱们聚焦的外围,能够自行查看。
Spring 的容器实现
咱们以更多应用的 java 配置 web 容器相干的一个具体实现举例:AnnotationConfigWebApplicationContext
对于应用模板办法设计模式相熟的小伙伴,肯定比拟相熟这类写法,而咱们次要的办法的外围实现在 AbstractApplicationContext#refresh 办法,该办法就是容器启动的生命周期,包含如下:
- 筹备 Environment
- 获取刷新之后的 BeanFactory
- 筹备实例化之后的 BeanFactory
- BeanFactory 的后置解决拓展办法
- 执行 BeanFactory 的后置处理器 BeanFactoryPostProcessor。这外面其中就有是 BeanDefinition 的扫描的拓展
- 注册 Bean 的后置处理器 BeanPostProcessor。这外面更多是一些依赖注入的后置处理器
- 初始化 messageSource
- 初始化事件播送器,用于事件监听器
- onRefresh 拓展办法
- 注册监听器
- 实现 BeanFactory 的初始化。这外面有 Bean 的生命周期的治理
- 实现刷新
Spring 的生命外围
咱们会去除一些监听器治理和资源管理等等这些其余性能的治理,以此更加聚焦的思考 Bean 的生命周期。去除之后的外围的容器的生命周期外围为以下几点:
- Environment 的治理
- BeanDefinition 的治理
- Bean 的生命周期
Environment 治理
把 Environment 领进去是因为咱们在加载 BeanDefinition 的时候须要这些配置,这一块的拓展也能够联合咱们配置核心加以举例。
BeanDefinition 治理
而对于 BeanDefinition 的治理,咱们以 Java 配置进行举例。BeanDefinition 的治理接口是 BeanDefinitionRegistry,会将 BeanDefinition 存储在容器内,供前期治理 Bean 的生命周期应用。
那么进一步去理解 BeanDefinition 的治理,咱们须要理解触发条件的治理,其中这些是由 BeanFactory 的后置处理器进行拓展管制,次要是以下步骤:
- BeanFactory 的后置处理器 ConfigurationClassPostProcessor 的加载
- BeanFactory 的后置处理器 ConfigurationClassPostProcessor 的执行
- BeanDefinition 的扫描
- BeanDefinition 的注册
加载
ConfigurationClassPostProcessor 的加载是在获取刷新 BeanFactory 曾经注册作为 BeanDefinition 的定义
执行
ConfigurationClassPostProcessor 的执行也是在容器执行 BeanFactory 的后置处理器会依据之前加载的后置处理器的 BeanDefinition 进行实例化,加载到容器外部,而后执行
扫描
BeanDefinition 的扫描,首先是从 BeanDefinition 的名字进行判断外面的 @Configuration 的定义。而后应用 ConfigurationClassParser#parse 解析 @Configuration 配置的类,将外面的注解进一步解析包含 @PropertySources、@ComponentScan、@ComponentScans、@Import、@ImportResource、@Bean
注册
ConfigurationClassParser 解析配置类的注解收集好信息,进一步应用 ConfigurationClassBeanDefinitionReader#loadBeanDefinitions 进行注册 BeanDefinition
Bean 的生命周期
之前咱们扫描完 BeanDefinition 之后,而后就能够进行 Bean 的整个生命过程,而 Bean 的生命开始个别都是走依赖查找的办法 AbstractBeanFactory#doGetBean,咱们以单例为例子,其余 scope 不进行赘述,次要有以下步骤:
- 从单例缓存中获取,同时对 FactoryBean 进行解决
- 从父容器进行依赖查找
- 对 Bean 的 DependsOn 有优先级须要依赖的 Bean 先依赖查找
- 单例进行实例化前置解决的拓展执行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 如果返回不为 null 的实例,则不进行往下执行
- 依据反射进行实例化
- 执行合并 BeanDefinition,执行 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
- 如果容许循环依赖,则先存储 Bean 实例化的 Factory,用于循环依赖执行获取晚期的 Bean
- 填充 Bean,进行执行实例化之后的后置处理器,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
- 填充 Bean,执行属性后置处理器,InstantiationAwareBeanPostProcessor#postProcessProperties
- 初始化 Bean,执行 Aware 前期处理器,比方 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
- 初始化 Bean,初始化之前的后置处理器
- 初始化 Bean,执行初始化办法,包含自定义
- 初始化 Bean,初始化之后的后置处理器
- 将单例进行存储缓存
依赖注入
以 @Resource 和 @Autowire 举例。而这两个解决都是以 BeanPostprocessor 进行拓展,首先须要将须要注入的信息进行扫描,应用 InjectedElement 进行存储,而后依据不同的状况进行注入。
@Resource 注入
应用 CommonAnnotationBeanPostProcessor 处理器拓展。
- buildResourceMetadata 办法扫描该办法外面标注 @Resource 等注解的属性或者办法
- @Resource 的元素的注入进行复写应用 getResource-》autowireResource 进行依赖查找
- 默认调用 beanFactory.resolveBeanByName 依据名字进行依赖查找
- 否则应用 beanFactory.resolveDependency 进行扫描所有的 Bean 的名字收集合乎须要注入类型的 Bean,而后依据多个首要的形式进行注入
@Autowire 注入
应用 AutowiredAnnotationBeanPostProcessor 处理器拓展。
- buildAutowiringMetadata 办法扫描标注了 @Autowire 等注解的属性或者办法
- @Autowire 的元素的注入 inject 办法复写应用 beanFactory.resolveDependency 进行依赖查找,扫描所有合乎类型,进行注入。