zoukankan      html  css  js  c++  java
  • spring

    spring 源码阅读

    IOC容器 实现

    • 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支持

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

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

      • HierarchicalBeanFactory interface

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

      • ListableBeanFactory interface

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

      • AutowireCapableBeanFactory interface

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

      • ConfigurableBeanFactory interface

      提供BeanFactory 配置功能

      • ConfigurableListableBeanFactory interface

      提供 额外的更多的 配置项

      • 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);
        }
    }
    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="user" class="com.joecqupt.beanfactory.User">
            <property name="name" value="joe"/>
            <property name="age" value="24"/>
        </bean>
    </beans>
    
    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代码继承关系

    • AttributeAccessor interface

      提供属性操作能力

    • BeanMetadataElement interface

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

    • 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 继承结构

      • PropertyEditorRegistry

        提供注册PropertyEditor的能力,

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

      • PropertyAccessor

        提供属性操作能力

        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

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

    • MessageSource

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

    • EnvironmentCapable

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

    • ApplicationEventPublisher

      事件发布器

    • ResourceLoader

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

    • ResourcePatternResolver

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

    • Lifecycle

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

    • ConfigurableApplicationContext

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

    Spring MVC 加载流程

    • ContextLoaderListener

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

      1. contextInitialized()

        开始去创建 WebApplicationContext ,WebApplicationContext继承层次如下:

  • 相关阅读:
    swoole 安装方法 使用即时聊天
    git的介绍以及简单应用
    curl的应用
    linux下监听和同步代码配置
    mac skim 修改背景色
    php 编译安装的一个 configure 配置
    mac mysql error You must reset your password using ALTER USER statement before executing this statement.
    yii2 控制器里 action 大小写组合造成的路由问题
    warning : json_decode(): option JSON_BIGINT_AS_STRING not implemented in xxx
    redis 自启动脚本
  • 原文地址:https://www.cnblogs.com/joeCqupt/p/11582124.html
Copyright © 2011-2022 走看看