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继承层次如下:

  • 相关阅读:
    图片体验(转载)
    addClass和css性能分析
    css选择器性能测试
    XHTML+CSS兼容性解决方案
    ASP.NET Club Web Site Starter Kit扩展之一
    CommunityServer从V1.1转换为V2.0的问题
    ASP.NET官方网站有中文版本了
    ASP.NET2.0登陆控件的使用(常见的三种方法)
    ASP.NET BLOGS Starter Kit(C#)准备发布
    基于Atlas地图使用
  • 原文地址:https://www.cnblogs.com/joeCqupt/p/11582124.html
Copyright © 2011-2022 走看看