• 《Spring源码深度解析》学习笔记——Spring的整体架构与容器的基本实现


    pring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块,如下图所示

    这些模块被总结为以下几个部分:

    • Core Container

      Core Container(核心容器)包含有Core、Beans、Context和Expression Language模块 
      Core和Beans模块是框架的基础部分,提供IoC(转控制)和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置

      • Core模块主要包含Spring框架基本的核心工具类
      • Beans模块是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control/Dependency Injection(Ioc/DI)操作相关的所有类
      • Context模块构建于Core和Beans模块基础之上,提供了一种类似于JNDI注册器的框架式的对象访问方法。Context模块继承了Beans的特性,为Spring核心提供了大量扩展,添加了对国际化(如资源绑定)、事件传播、资源加载和对Context的透明创建的支持。ApplicationContext接口是Context模块的关键
      • Expression Language模块提供了一个强大的表达式语言用于在运行时查询和操纵对象,该语言支持设置/获取属性的值,属性的分配,方法的调用,访问数组上下文、容器和索引器、逻辑和算术运算符、命名变量以及从Spring的IoC容器中根据名称检索对象
    • Data Access/Integration

      • JDBC模块提供了一个JDBC抽象层,它可以消除冗长的JDBC编码和解析数据库厂商特有的错误代码,这个模块包含了Spring对JDBC数据访问进行封装的所有类
      • ORM模块为流行的对象-关系映射API,如JPA、JDO、Hibernate、iBatis等,提供了一个交互层,利用ORM封装包,可以混合使用所有Spring提供的特性进行O/R映射,如前边提到的简单声明性事务管理
    • Web

      Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文,所以Spring框架支持与Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。Web层包含了Web、Web-Servlet、Web-Struts和Web、Porlet模块

      • Web模块:提供了基础的面向Web的集成特性,例如,多文件上传、使用Servlet listeners初始化IoC容器以及一个面向Web的应用上下文,它还包含了Spring远程支持中Web的相关部分
      • Web-Servlet模块web.servlet.jar:该模块包含Spring的model-view-controller(MVC)实现,Spring的MVC框架使得模型范围内的代码和web forms之间能够清楚地分离开来,并与Spring框架的其他特性基础在一起
      • Web-Struts模块:该模块提供了对Struts的支持,使得类在Spring应用中能够与一个典型的Struts Web层集成在一起
      • Web-Porlet模块:提供了用于Portlet环境和Web-Servlet模块的MVC的实现
    • AOP

      AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现,它让你可以定义例如方法拦截器和切点,从而将逻辑代码分开,降低它们之间的耦合性,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中

      Spring AOP模块为基于Spring的应用程序中的对象提供了事务管理服务,通过使用Spring AOP,不用依赖EJB组件,就可以将声明性事务管理集成到应用程序中

    • Test

      Test模块支持使用Junit和TestNG对Spring组件进行测试

    容器的基本实现

    Spring的结构组成

    beans包的层级结构

    beans包中的各个源码包的功能如下

    • src/main/java 用于展现Spring的主要逻辑
    • src/main/resources 用于存放系统的配置文件
    • src/test/java 用于对主要逻辑进行单元测试
    • src/test/resources 用于存放测试用的配置文件

    核心类介绍

    1.DefaultListableBeanFactory

    XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册及加载bean的默认实现,而对于XmlBeanFactory与DefaultListableBeanFactory不同的地方其实是在XmlBeanFactory中使用了自定义的XML读取器XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader读取,DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory并实现了ConfigURableListableBeanFactory以及BeanDefinitionRegistry接口。以下是ConfigURationListableBeanFactory的层次结构图以下相关类图

    容器加载相关类图

    类图中各个类的作用:

    • AliasRegistry:定义对alias的简单增删改等操作
    • SimpleAliasRegistry:主要使用map作为alias的缓存,并对接口AliasRegistry进行实现
    • SingletonBeanRegistry:定义对单例的注册及获取
    • BeanFactory:定义获取bean及bean的各种属性
    • DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现
    • HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持
    • BeanDefinitionRegistry:定义对BeanDefinition的各种增删改操作
    • FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能
    • ConfigurableBeanFactory:提供配置Factory的各种方法
    • ListableBeanFactory:根据各种条件获取bean的配置清单
    • AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurationBeanFactory的功能
    • AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器
    • AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口AutowireCapableBeanFactory进行实现
    • ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等
    • DefaultListableBeanFactory:综合上面所有功能,主要是对Bean注册后的处理

    2.XmlBeanDefinitionReader

    XML配置文件的读取是Spring中重要的功能,因为Spring的大部分功能都是以配置作为切入点的,可以从XmlBeanDefinitionReader中梳理一下资源文件读取、解析及注册的大致脉络,首先看看各个类的功能

    • ResourceLoader:定义资源加载器,主要应用于根据给定的资源文件地址返回对应的Resource
    • BeanDefinitionReader:主要定义资源文件读取并转换为BeanDefinition的各个功能
    • EnvironmentCapable:定义获取Environment方法
    • DocumentLoader:定义从资源文件加载到转换为Document的功能
    • AbstractBeanDefinitionReader:对EnvironmentCapable、BeanDefinitionReader类定义的功能进行实现
    • BeanDefinitionDocumentReader:定义读取Document并注册BeanDefinition功能
    • BeanDefinitionParserDelegate:定义解析Element的各种方法

    整个XML配置文件读取的大致流程,在XmlBeanDefinitionReader中主要包含以下几步处理

    (1)通过继承自AbstractBeanDefinitionReader中的方法,来使用ResourceLoader将资源文件路径转换为对应的Resource文件

    (2)通过DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件

    (3)通过实现接口BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader类对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析

    容器的基础XmlBeanFactory

    BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
    

    通过XmlBeanFactory初始化时序图看一看上面代码的执行逻辑

    时序图从BeanFactoryTest测试类开始,首先调用ClassPathResource的构造函数来构造Resource资源文件的实例对象,这样后续的资源处理就可以用Resource提供的各种服务来操作了

    配置文件封装

    Spring的配置文件读取是通过ClassPathResource进行封装的,Spring对其内部使用到的资源实现了自己的抽象结构:Resource接口来封装底层资源

    public interface InputStreamSource {
        InputStream getInputStream() throws IOException;
    }
    public interface Resource extends InputStreamSource {
        boolean exists();
    
        boolean isReadable();
    
        boolean isOpen();
    
        URL getURL() throws IOException;
    
        URI getURI() throws IOException;
    
        File getFile() throws IOException;
    
        long lastModified() throws IOException;
    
        Resource createRelative(String var1) throws IOException;
    
        String getFilename();
    
        String getDescription();
    }

    InputStreamSource封装任何能返回InputStream的类,比如File、Classpath下的资源和Byte Array等, 它只有一个方法定义:getInputStream(),该方法返回一个新的InputStream对象

    Resource接口抽象了所有Spring内部使用到的底层资源:File、URL、Classpath等。首先,它定义了3个判断当前资源状态的方法:存在性(exists)、可读性(isReadable)、是否处于打开状态(isOpen)。另外,Resource接口还提供了不同资源到URL、URI、File类型的转换,以及获取lastModified属性、文件名(不带路径信息的文件名,getFilename())的方法,为了便于操作,Resource还提供了基于当前资源创建一个相对资源的方法:createRelative(),还提供了getDescription()方法用于在错误处理中的打印信息

    对不同来源的资源文件都有相应的Resource实现:文件(FileSystemResource)、Classpath资源(ClassPathResource)、URL资源(UrlResource)、InputStream资源(InputStreamResource)、Byte数组(ByteArrayResource)等,相关类图如下所示



  • 相关阅读:
    程序员常见的坏习惯,你躺枪了吗?
    程序员常见的坏习惯,你躺枪了吗?
    程序员常见的坏习惯,你躺枪了吗?
    ACM2037
    [Golang]字符串拼接方式的性能分析
    如果一个类同时继承的两个类都定义了某一个函数会怎样呢 | Code4Fun
    Python学习笔记(四)函数式编程
    MySql之增删改查 · YbWork's Studio
    季銮西的博客
    ActiveMQ学习总结(一)
  • 原文地址:https://www.cnblogs.com/zhimingxin/p/7447810.html
Copyright © 2020-2023  润新知