阅读Spring源码(1) - 上下文启动

Spring的整体架构和环境搭建

spring5 源码深度解析—–Spring的整体架构和环境搭建 - chen_hao - 博客园

Spring的整体架构

  • Core Container
    • Core
    • Beans
    • Context
    • SpEL
  • AOP
  • Aspect
  • Instrumentation
  • Messaging
  • Web
    • Web
    • Servlet
    • Websocket
    • Portlet
  • Data Access/Integration
    • JDBC
    • ORM
    • OXM
    • JMS
    • Transactions
  • Test

阅读步骤

  1. 安装gradle
  2. 下载源码
  3. build项目
  4. 创建测试模块并debug

IOC注册

spring5 源码深度解析—– IOC 之 容器的基本实现 - chen_hao - 博客园

spring5 源码深度解析—– IOC 之 默认标签解析(上) - chen_hao - 博客园

spring5 源码深度解析—– IOC 之 默认标签解析(下) - chen_hao - 博客园

ClassPathResource, Resource 配置资源的抽象

示例使用 XmlBeanFactory

BeanFactoryAware/ApplicationContextAware 在构建BeanFactory的时候就进行了相关配置

XmlBeanDefinitionReader 解析XML文件, 返回 org.w3c.dom.Document

BeanDefinitionDocumentReader 使用 BeanDefinitionParserDelegate 解析Document, 包含defaultElement/customElement, 返回 BeanDefinitionHolder (包含 GenericBeanDefinition)

BeanDefinitionDocumentReader 将 <beanName, beanDefinition> 注册到 BeanDefinitionRegistry(beanFactory), 实际使用 DefaultListableBeanFactoryregisterBeanDefinition, 映射关系保存在一个ConcurrentHashMap中

IOC注入(BeanFactory)

spring5 源码深度解析—– IOC 之 开启 bean 的加载 - chen_hao - 博客园

BeanFactory

BeanFactory类图

BeanFactoryFactoryBean 的区别:

  • BeanFactory, 访问 Spring bean 容器的根接口, 是应用程序组件的中央注册表
  • FactoryBean, 如果一个 bean 实现了这个接口,它就被用作一个对象暴露的工厂

获取bean名称

AbstractBeanFactorytransformedBeanName

  1. FactoryBean的&名称解引用
  2. alias转换

获取单例缓存sharedInstance

DefaultSingletonBeanRegistrygetSingleton()

几个缓存(使用时不加锁的是ConcurrentHashMap, 使用时加锁的是HashMap)

  • singletonObjects:用于保存BeanName和创建bean实例之间的关系,beanName–>bean Instance
  • singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,banName–>ObjectFactory
  • earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用

如果有单例缓存, 则使用单例缓存获取bean

如果单例缓存不是FactoryBean则说明为bean直接返回

如果单例缓存是FactoryBean则调用getBean, DefaultSingletonBeanRegistrybeforeSingletonCreation afterSingletonCreation 继续使用缓存判断是否创建中(检测循环引用), postProcessObjectFromFactoryBean 调用bean的 BeanPostProcessors 方法

创建bean

spring5 源码深度解析—– IOC 之 bean 创建 - chen_hao - 博客园

未获取到单例缓存的话就要创建bean

入口 AbstractBeanFactorydoGetBean()

scope=singleton

  1. synchronized全局锁
  2. 检查缓存
  3. beforeSingletonCreation()
  4. createBean()
  5. afterSingletonCreation()
  6. 加入缓存

scope=prototype

  1. beforeSingletonCreation()
  2. createBean()
  3. afterSingletonCreation()
  4. getObjectForBeanInstance()

scope=other

  1. beforeSingletonCreation()
  2. scope.get() -> createBean()
  3. afterSingletonCreation()
  4. getObjectForBeanInstance()

实现的方法createBean()

AbstractAutowireCapableBeanFactorycreateBean()