spring

spring 源码阅读

IOC容器 实现

spring_第1张图片

  • AliasRegistry interface

    提供别名注册的能力 实现有
    1. SimpleAliasRegistry 使用ConcurrentHashMap实现别名注册
  • BeanDefinitionRegistry interface

    提供了BeanDefinition注册的能力,实现有
    1. SimpleBeanDefinitionRegistry 使用ConcurrentHashMap实现,同时这个类继承SimpleAliasRegistry 提供别名和beanDefinition注册的双重能力
    2. DefaultListableBeanFactory //TODO 后面详细介绍
  • SingletonBeanRegistry interface

    提供单例对象注册的能力 实现有
    1. DefaultSingletonBeanRegistry
      这个类还继承了 SimpleAliasRegistry,拥有别名注册的能力,
      实现比较复杂!!

    2. FactoryBeanRegistrySupport

    提供和 工厂bean创建的对象 cache支持

    spring_第2张图片

    1. ConfigurableBeanFactory interface //TODO 后面介绍
  • BeanFactory interface

    提供spring ioc 容器的基本功能,包含bean的获取、别名的获取、bean是否存在的判断等等...

    spring_第3张图片

    • HierarchicalBeanFactory interface

    BeanFactory的扩展,提供parentBeanFactory的支持,更大范围搜索:

    spring_第4张图片

    • ListableBeanFactory interface

    提供了很多bean、beanName、beanDefinition的获取手段

    spring_第5张图片

    • AutowireCapableBeanFactory interface

    提供bean创建、bean注入、bean销毁、属性注入、BeanPostProcessor调用等等等功能

    spring_第6张图片

    • ConfigurableBeanFactory interface

    提供BeanFactory 配置功能

    spring_第7张图片

    • ConfigurableListableBeanFactory interface

    提供 额外的更多的 配置项

    spring_第8张图片

    • AbstractBeanFactory

    从IOC容器类uml图看,该类 的功能比较少,没有注入功能,没有beanDefinition注册功能等等

    • AbstractAutowireCapableBeanFactory

    扩展AbstractBeanFactory, 提供了bean注入功能

    • DefaultListableBeanFactory

    BeanFactory的完全体,提供单例注册,别名注册,beanDefinition注册,BeanFactory等等功能

    • XmlBeanFactory

    DefaultListableBeanFactory 的一个实现,主要实现读取Xml配置,注册BeanDefinition的功能

### XmlBeanFactory 解析

  • 简单使用
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class XmlBeanFactoryTest {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("application.xml");
        XmlBeanFactory beanFactory  = new XmlBeanFactory(resource);
        User user = beanFactory.getBean(User.class);
        System.out.println(user);
    }
}



    
        
        
    
import lombok.Data;

@Data
public class User {
    private String name;
    private int age;
}
  • 源码解析

    1. XmlBeanFactory 使用 XmlBeanDefinitionReader读取Xml配置信息
    2. XmlBeanBeanDefinitionReader 构造函数需要一个 BeanDefinitionRegistry对象,因为它会将读取的配置注册进去,XmlBeanFactory刚好实现了BeanDefinitionRegistry接口
    3. XmlBeanDefinitionReader 会将配置文件xml解析成 Document对象,然后借助XmlBeanDefinitionDocumentReader SAX解析将Document解析成BeanDefinition
    4. XmlBeanDefinitionDocumentReader会委托 BeanDefinitionParserDelegate代理解析 Element 为 BeanDefinition
      1. BeanDefinitionParserDelegate 根据namespace来解析ELement,如果是默认的namespace使用delegate解析,如果是其他的namespace则使用 对用的XXXNameSpaceHandler对Element进行解析
      2. 解析Bean Element(主要讲一下property的解析方式) 会将property属性解析为PropertyValue,添加到BeanDefinition对象的propertyValues列表中去。
  • BeanDefinition代码继承关系

spring_第9张图片

  • AttributeAccessor interface

    提供属性操作能力

    spring_第10张图片

  • BeanMetadataElement interface

    提供获取当前配置获取的 Element信息

    1114580-20190914023255822-516698446.png

  • BeanDefinition interface

    提供了BeanDefinition各种配置项目

  • AttributeAccessorSupport

    提供属性操作能力实现,内部使用map存储属性,对属性的操作映射到对此map的操作

  • BeanMetadataAttributeAccessor

    提供了BeanMetadataAttribute的注册和获取能力

  • AbstractBeanDefinition

    提供了BeanDefinition更多的配置项

  • GenericBeanDefinition

    提供了parentName的设置

NamespaceHander

默认的namespace(等),BeanDefinitionParserDelegate 就可以解析,但是不是默认配置等等是需要注册专用的NamespaceHandler才能解析的。

spring 借助 NamespaceHandlerResolver 和 NamespaceHandler 两个接口来实现, NamespaceHandlerResolver 会默认加载所有jar包的 META-INF/spring.handlers 的配置,然后获取到目前支持的 namespace-namespceHandler的映射。
NamespaceHandler中的init方法会 注册该namespace下 elementName - BeanDefinitionParser的映射

在XmlBeanFactory中获取bean

在以前的工作中,xmlBeanFactory做的工作只是将xml文件的配置转化为了BeanDefinition注册到了XmlBeanFactory中去。

通过getBean()方法可以从BeanFactory中获取 Bean的实例

源码解析getBean(beanName)

  1. 实现的类在AbstractBeanFactory,首先回去尝试加载一下 已经成功加载的单例bena缓存中获取一下当前beanName是否存在
    • 如果获取不到,表明此bean没有被加载过
    • 如果获取到了 // todo
  2. 如果parentBeanFactory不为空,然后尝试去 parentBeanFactory中去获取一下
  3. 这才开始真正的bean加载过程了。
    • 首先 标记这个bean已经创建 在 alreadyCreated 中添加此beanName
    • 然后 同时移除 mergedBeanDefinitions 中的该bean的RootBeanDefinition
      因为要去创建bean,所以要重新去merge一次beanDefinition
  4. 开始merge BeanDefinition (会将读取xml配置获取到的GenericBeanDefinition 转换成 RootBeanDefinition)
  5. merge之后出口 depend-on属性,递归时初始化 depend-on的bean,同时检查循环 depend-on
  6. 开始去 缓存拿一下beanName对应的单例,如果没有拿到,那就去执行真正的创建bean的操作
  7. 开始处理BeanDefinition的 methodOverrides 配置
  8. 开始处理 BeanDefinition的 InstantiationAwareBeanPostProcessor 处理器 ,这个处理器能在真正去创建bean之前返回bean实例, (Aop就是通过这种方式来实现的) //todo
    1. 会调用 InstantiationAwareBeanPostProcessor处理器的postProcessBeforeInstantiation 方法
    2. 如果 前一个处理方法获取到了对象,那么会调用所有的BeanPostProcessor 的
    postProcessAfterInitialization 方法
ps 一个是 before实例化方法  一个是after初始化方法,仔细理解一下这个意思,bean的生命周期应该是:  
实例化 -->  初始化 
  1. 开始去创建实例,首先先去 factoryBean实例缓存中 获取一下,该实例是否存在?(其实据我理解这个缓存中放的就是实例化好的对象,但是还没进行属性注入),如果获取到了就不用去实例化bean,如果没有获取到就要去实例化bean!!
  2. 实例化bean
    1. 通过提供Supplier 方法进行实例化
    2. 通过提供的 工厂方法实例化
    3. 通过某种策略来选择构造器进行Bean实例化 // todo 很复杂 下来了解
      • 如果有设置SmartInstantiationAwareBeanPostProcessor,这个处理器可覆盖方法来决定使用哪一个构造器
    4. 实例化的过程,如果有设置 MethodOverrides 则使用过CGlib实例化,如果没有则使用反射的方式实例化

    只要记得这一步的结果就是会得到一个Bean的实例,这个bean实例会装进BeanWrapper实例中

    BeanWrapper 继承结构
    spring_第11张图片

    • PropertyEditorRegistry

      提供注册PropertyEditor的能力,

      PropertyEditor属性编辑类:提供属性获取、属性设置和属性变更监听器的功能

    • PropertyAccessor

      提供属性操作能力

      spring_第12张图片

      TypeDescriptor 类型描述类,提供该类型的全方位描述(包含该类型的Class和注解等)

    • TypeConverter

      类型转换的能力

    • ConfigurablePropertyAccessor

      提供设置和获取 ConversionService 的能力 ,ConversionService 是自从spring3.0以来提供的类型转换工具

    • BeanWrapper

      提供 设置和获取被包装实例的方法,提供设置和获取PropertyDescriptor的方法;

      PropertyDescriptor属性描述类:提供获取 当前属性的class,当前属性的 get、set方法等功能

    • PropertyEditorRegistrySupport

      可以设置默认的一些 PropertyEditor

    • TypeConverterSupport

      使用TypeConverterDelegate类进行 类型装换 // 还是有点复杂的

    • AbstractPropertyAccessor

      主要是实现了 PropertyAccessor 接口的方法,实现对属性的设置功能

    • AbstractNestablePropertyAccessor

      nestable 可嵌套的

    • BeanWrapperImpl

      以上功能集大成者

  3. bean实例化之后 如果bean是单例类型并允许循环依赖,那么去 注册一个用于早期暴露的 beanFactory,
    1. 这个beanFactory返回的是bean实例就是刚刚实例化后的对象(此时各个属性值还没有设置),
    2. 如果有设置 SmartInstantiationAwareBeanPostProcessor 处理器,那么这个BeanFactory会返回处理器处理后的 bean实例 (AOP有实现这个处理器)
  4. 开始给bean设置属性值
    1. 执行 实例化后处理器 InstantiationAwareBeanPostProcessor postProcessAfterInstantiation方法
    2. 执行属性处理方法 InstantiationAwareBeanPostProcessor postProcessProperties方法和postProcessPropertyValues方法
      (@AutoWired @Resource 等功能就是这里处理的)

    3. 执行 属性值 解析器:是把 XML属性设置的格式 解析出来 (比如属性可以设置 ref list map 等等格式)
    4. 转化器工作: 这里回去做转换,去看看setter需要什么类型,就把属性值转换成某种类型
    5. 通过自省去给bean实例设置 属性值 (注意这里有嵌套 属性值得设置处理 )
  5. 执行初始化
    1. 执行一些 *Aware接口的信息注入
    2. 执行处理器 postProcessBeforeInitialization 方法
    3. 执行InitializingBean接口 指定的方法 afterPerprotiesSet() 或者 执行自定义的 init 方法
    4. 执行postProcessAfterInitialization 方法
    5. 自此bean的实例化初始化全部完成了
  6. 注册bean销毁处理器
  7. 从创建好的bean中获取bean实例,主要是对FactoryBean进行处理,需要调用getObejct方法
  8. 从IOC容器中返回bean完成

ApplicationContext

spring_第13张图片

继承结构如图,BeanFactory 那一段可以不用看了,看看新的这些接口

  • MessageSource

    一个支持国际化的信息(message)处理器
  • EnvironmentCapable

    环境感知接口,能够获取到当前 Environment 环境对象
  • ApplicationEventPublisher

    事件发布器
  • ResourceLoader

    资源加载器, 只有两个方法,获取ClassLoader对象 和 获取Resource对象
  • ResourcePatternResolver

    资源加载器的扩展, 提供 获取Resource[] 数组的能力
  • Lifecycle

    提供声明周期支持, 提供生命周期控制,只提供3个方法 start() stop() isRunning()
  • ConfigurableApplicationContext

    提供application的配置功能,它新增的方法如下:

    spring_第14张图片

Spring MVC 加载流程

  • ContextLoaderListener

    继承自ServletContextListener, 会在context创建和销毁的过程中,会自动调用 contextInitialized() contextDestroyed()
    1. contextInitialized()

      开始去创建 WebApplicationContext ,WebApplicationContext继承层次如下:
      spring_第15张图片

转载于:https://www.cnblogs.com/joeCqupt/p/11582124.html

你可能感兴趣的:(spring)