总概

最近始终在思考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。
外围接口:

  1. EnvironmentCapable:提供获取Environment接口
  2. ListableBeanFactory/BeanFactory:提供Bean依赖查找。

    至于其余的接口不是咱们聚焦的外围,能够自行查看。

Spring的容器实现

咱们以更多应用的java配置web容器相干的一个具体实现举例:AnnotationConfigWebApplicationContext

对于应用模板办法设计模式相熟的小伙伴,肯定比拟相熟这类写法,而咱们次要的办法的外围实现在AbstractApplicationContext#refresh办法,该办法就是容器启动的生命周期,包含如下:

  1. 筹备Environment
  2. 获取刷新之后的BeanFactory
  3. 筹备实例化之后的BeanFactory
  4. BeanFactory的后置解决拓展办法
  5. 执行BeanFactory的后置处理器BeanFactoryPostProcessor。这外面其中就有是BeanDefinition的扫描的拓展
  6. 注册Bean的后置处理器BeanPostProcessor。这外面更多是一些依赖注入的后置处理器
  7. 初始化messageSource
  8. 初始化事件播送器,用于事件监听器
  9. onRefresh拓展办法
  10. 注册监听器
  11. 实现BeanFactory的初始化。这外面有Bean的生命周期的治理
  12. 实现刷新

Spring的生命外围

咱们会去除一些监听器治理和资源管理等等这些其余性能的治理,以此更加聚焦的思考Bean的生命周期。去除之后的外围的容器的生命周期外围为以下几点:

  1. Environment的治理
  2. BeanDefinition的治理
  3. Bean的生命周期

Environment治理

把Environment领进去是因为咱们在加载BeanDefinition的时候须要这些配置,这一块的拓展也能够联合咱们配置核心加以举例。

BeanDefinition治理

而对于BeanDefinition的治理,咱们以Java配置进行举例。BeanDefinition的治理接口是BeanDefinitionRegistry,会将BeanDefinition存储在容器内,供前期治理Bean的生命周期应用。
那么进一步去理解BeanDefinition的治理,咱们须要理解触发条件的治理,其中这些是由BeanFactory的后置处理器进行拓展管制,次要是以下步骤:

  1. BeanFactory的后置处理器ConfigurationClassPostProcessor的加载
  2. BeanFactory的后置处理器ConfigurationClassPostProcessor的执行
  3. BeanDefinition的扫描
  4. 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不进行赘述,次要有以下步骤:

  1. 从单例缓存中获取,同时对FactoryBean进行解决
  2. 从父容器进行依赖查找
  3. 对Bean的DependsOn有优先级须要依赖的Bean先依赖查找
  4. 单例进行实例化前置解决的拓展执行InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation如果返回不为null的实例,则不进行往下执行
  5. 依据反射进行实例化
  6. 执行合并BeanDefinition,执行MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
  7. 如果容许循环依赖,则先存储Bean实例化的Factory,用于循环依赖执行获取晚期的Bean
  8. 填充Bean,进行执行实例化之后的后置处理器,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
  9. 填充Bean,执行属性后置处理器,InstantiationAwareBeanPostProcessor#postProcessProperties
  10. 初始化Bean,执行Aware前期处理器,比方BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
  11. 初始化Bean,初始化之前的后置处理器
  12. 初始化Bean,执行初始化办法,包含自定义
  13. 初始化Bean,初始化之后的后置处理器
  14. 将单例进行存储缓存

依赖注入

以@Resource和@Autowire举例。而这两个解决都是以BeanPostprocessor进行拓展,首先须要将须要注入的信息进行扫描,应用InjectedElement进行存储,而后依据不同的状况进行注入。

@Resource注入

应用CommonAnnotationBeanPostProcessor处理器拓展。

  1. buildResourceMetadata办法扫描该办法外面标注@Resource等注解的属性或者办法
  2. @Resource的元素的注入进行复写应用getResource-》autowireResource进行依赖查找
  3. 默认调用beanFactory.resolveBeanByName依据名字进行依赖查找
  4. 否则应用beanFactory.resolveDependency进行扫描所有的Bean的名字收集合乎须要注入类型的Bean,而后依据多个首要的形式进行注入
@Autowire注入

应用AutowiredAnnotationBeanPostProcessor处理器拓展。

  1. buildAutowiringMetadata办法扫描标注了@Autowire等注解的属性或者办法
  2. @Autowire的元素的注入inject办法复写应用beanFactory.resolveDependency进行依赖查找,扫描所有合乎类型,进行注入。