1 Spring 框架

Spring 是一个轻量级的 Java 开发框架,,旨在提高开发人员的开发效率以及系统的可维护性。
Spring 的核心是控制反转 (IoC)和面向切面编程 (AOP)。
Spring 是一个存储对象的容器,容器内不装文本、数字,只装对象。
Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在 Spring 中说明对象(模块)的关系。

Spring 根据代码的功能特点,使用 IOC 降低业务对象之间耦合度。 IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring 容器统一管理,自动“注入” 注入即赋值。而 AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。

官方网站:Spring | Home
Spring 框架文档:Spring Framework Documentation
Spring 框架 API:Overview (Spring Framework 5.3.12 API)
Spring 源码:GitHub - spring-projects/spring-framework: Spring Framework

2 Spring 核心

(1) IOC (Inversion of Control 控制反转) 或 DI (Dependency Injection 依赖注入)

  • IOC:说简单点就是当我们使用对象调用一个方法或者类时,不再由我们主动去创建这个类的对象,控制权交给 Spring 框架。说复杂点就是资源不再由使用资源双方进行管理,而是由不使用资源的第三方统一管理,这样带来的好处。第一,资源的集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。
  • DI:由 Spring 框架主动创建被调用类的对象,然后把这个对象注入到我们自己的类中,使得我们可以直接使用它。

(2) AOP(Aspect Oriented Programming 面向切面编程)

  • AOP:说简单点就是我们可以在不修改源代码的情况下,对程序的方法进行增强。说复杂点就是将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定的位置中。即系统级的服务从代码中解耦出来。例如:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来。提高程序的可重用性,同时提高了开发的效率。

3 Spring 优缺点

优点

  1. 方便解耦,简化开发:通过 IOC 容器,(1) 将对象之间的依赖关系交给 Spring 处理 (2) 降低定义变量时的硬编码问题,减少过度耦合 (3) IOC 容器的单实例机制,用户不用自己完成单例配置。Spring 提高很多已有实现,如属性文件解析等代码,开发人员只需要关注上层引用。
  2. AOP 编程的支持:方便进行面向切面的编程。
  3. 事务的支持:通过注解声明进行事务管理,提高开发效率和质量。
  4. 方便程序的测试:Spring 对 Junit 支持,可以通过注解方便的测试 Spring 程序。
  5. 方便集成各种优秀框架:Spring 提供了对各种优秀框架(如 Struts, Hibernate、Hessian、Quartz)等的直接支持。
  6. 轻量级的框架:从大小与开销两方面而言 Spring 都是轻量的。现在完整的 Spring 5 框架只有 82 MB。并且 Spring 所需的处理开销也是微不足道的。
  7. 非入侵式的框架:Spring 框架是一个非入侵式的框架,就是我们的系统使用了 Spring,但系统完全不依赖于 Spring 的特定类。
  8. 降低 Java EE API 的使用难度:Spring 对很多难用的 Java EE API(如 JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过 Spring 的简易封装,这些 Java EE API 的使用难度大为降低。
  9. Java 源码是经典学习范例:Spring 的源码设计精妙、结构清晰、匠心独运,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。Spring 框架源码无疑是 Java 技术的最佳实践范例。如果想在短时间内迅速提高自己的 Java 技术水平和应用开发水平,学习和研究 Spring 源码将会使你收到意想不到的效果。

缺点

  1. 不易拆分:Spring 框架整合其它框架都是黏在一起,后面拆分的话就不容易拆分了。
  2. 配置繁琐:随着系统工程的增大,系统与第三方的配置文件会大量增加,这也是 Spring 最致命的地方,人称:“配置地狱”。
  3. 依赖反射:Spring 依赖反射,反射影响性能。
  4. 有更好的替代品:对比新出的 SpringBoot,他已经逐渐占领了市场。

4 Spring 体系结构

Spring 框架包含的功能大约由 20 个小模块组成。这些模块按组可分为核心容器 (Core Container)、数据访问/集成 (Data Access/Integration)、Web、面向切面编程 (AOP 和 Aspects)、设备 (Instrumentation)、消息 (Messaging) 和测试 (Test)。如下图所示:

Spring Framework Runtime|500
Spring core:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
Spring beans:提供了 BeanFactory,是工厂模式的一个经典实现,Spring 将管理对象称为 Bean。
Spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
Spring jdbc:提供了一个 JDBC 的抽象层,消除了烦琐的 JDBC 编码和数据库厂商特有的错误代码解析,用于简化 JDBC。
Spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
Spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
Spring test:主要为测试提供支持的,支持使用 JUnit 或 TestNG 对 Spring 组件进行单元测试和集成测试。

5 Spring 体系结构详细

(1)  核心容器 (Core Container)——Beans、Core、Context、Expression

该层由 4 个模块组成:Spring-beans Spring-core Spring-context Spring-expression (Spring expression Language, SpEl) 。它们对应的 jar 包如下:

  1. Spring-core:该模块是依赖注入 IoC 与 DI 的最基本实现。
  2. Spring-beans:该模块是 Bean 工厂与 bean 的装配。
  3. Spring-context:该模块构架于核心模块之上,它扩展了 BeanFactory,为它添加了 Bean 生命周期控制、框架事件体系以及资源加载透明化等功能。ApplicationContext 是该模块的核心接口,它的超类是 BeanFactory。与 BeanFactory 不同,ApplicationContext 容器实例化后会自动对所有的单实例 Bean 进行实例化与依赖关系的装配,使之处于待用状态。
  4. Spring-context-indexer:该模块是 Spring 的类管理组件和 Classpath 扫描。
  5. Spring-context-support:该模块是对 Spring IOC 容器的扩展支持,以及 IOC 子容器。
  6. Spring-expression:该模块是 Spring 表达式语言块是统一表达式语言(EL)的扩展模块,可以查询、管理运行中的对象,同时也方便的可以调用对象方法、操作数组、集合等。

(2) 数据访问与集成 (Data Access/Integration)——Jdbc、Orm、Oxm、Jms、Transactions

该层由 Spring-jdbc、Spring-tx、Spring-orm、Spring-jms 和 Spring-oxm 5 个模块组成。它们对应的 jar 包如下:

  1. Spring-jdbc:该模块提供了 JDBC 抽象层,它消除了冗长的 JDBC 编码和对数据库供应商特定错误代码的解析。
  2. Spring-tx:该模块支持编程式事务和声明式事务,可用于实现了特定接口的类和所有的 POJO 对象。编程式事务需要自己写 beginTransaction ()、commit ()、rollback () 等事务管理方法,声明式事务是通过注解或配置由 Spring 自动处理,编程式事务粒度更细。
  3. Spring-orm:该模块提供了对流行的对象关系映射 API 的集成,包括 JPA、JDO 和 Hibernate 等。通过此模块可以让这些 ORM 框架和 Spring 的其它功能整合,比如前面提及的事务管理。
  4. Spring-oxm:该模块提供了对 OXM 实现的支持,比如 JAXB、Castor、XML Beans、JiBX、XStream 等。
  5. Spring-jms:该模块包含生产(produce)和消费(consume)消息的功能。从 Spring 4.1 开始,集成了 Spring-messaging 模块。

(3) Web——Web、Webmvc、WebFlux、Websocket

该层由 Spring-web、Spring-webmvc、Spring-websocket 和 Spring-webflux 4 个模块组成。它们对应的 jar 包如下:

  1. Spring-web:该模块为 Spring 提供了最基础 Web 支持,主要建立于核心容器之上,通过 Servlet 或者 Listeners 来初始化 IOC 容器,也包含一些与 Web 相关的支持。
  2. Spring-webmvc:该模块众所周知是一个的 Web-Servlet 模块,实现了 Spring MVC(model-view-Controller)的 Web 应用。
  3. Spring-websocket:该模块主要是与 Web 前端的全双工通讯的协议。
  4. Spring-webflux:该模块是一个新的非堵塞函数式 Reactive Web 框架,可以用来建立异步的,非阻塞,事件驱动的服务,并且扩展性非常好。

(4) 面向切面编程——AOP,Aspects

该层由 Spring-aop 和 Spring-aspects 2 个模块组成。它们对应的 jar 包如下:

  1. Spring-aop:该模块是 Spring 的另一个核心模块,是 AOP 主要的实现模块**。**
  2. Spring-aspects:该模块提供了对 AspectJ 的集成,主要是为 Spring AOP 提供多种 AOP 实现方法,如前置方法后置方法等。

(5) 设备 (Instrumentation)——Instrmentation

Spring-instrument:该模块是基于 JAVA SE 中的”java. Lang. Instrument”进行设计的,应该算是 AOP 的一个支援模块,主要作用是在 JVM 启用时,生成一个代理类,程序员通过代理类在运行时修改类的字节,从而改变一个类的功能,实现 AOP 的功能。

(6) 消息 (Messaging)——Messaging

Spring-messaging:该模块是从 Spring 4 开始新加入的一个模块,主要职责是为 Spring 框架集成一些基础的报文传送应用。

(7) 测试(Test)——Test

Spring-test:该模块主要为测试提供支持的,通过 JUnit 和 TestNG 组件支持单元测试和集成测试。它提供了一致性地加载和缓存 Spring 上下文,也提供了用于单独测试代码的模拟对象(mock object)。

6 Spring 6 特点

Spring 6 要求 JDK 最低版本是 JDK 17

7 Spring 设计模式

  • 工厂设计模式 : Spring 使用工厂模式通过 BeanFactoryApplicationContext 创建 bean 对象。
  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  • 代理设计模式 : Spring AOP 功能的实现是 JDK 动态代理或 CGLIB 字节码生成技术。
  • 适配器模式 : Spring AOP 的增强或通知 (Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配 Controller
  • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
  • 装饰者模式: Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源。我们能否根据客户的需求在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式 (这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有 Wrapper 或者 Decorator。这些类基本上都是动态地给一个对象添加一些额外的职责.

详细见:面试官:“谈谈 Spring 中都用到了那些设计模式?”。

8 Spring 拓展

Spring 框架经过这么多年的发展,它已经衍生出了一个非常庞大的体系,有 SpringBoot、SpringCloud 等等。如下图所示:

image

  • SpringBoot 的设计目的是用来简化 Spring 应用的开发过程。现在大部分企业都在使用 SpringBoot 进行快速开发,SpringBoot 内部集成了很多第三方库的配置,所以它开箱即用。而且能够快速整合第三方框架,无需配置繁琐的文件,解决了 Spring 的弊端。基于 Spring Boot 可以快速的开发单个微服务。 SpringBoot 的约定大于配置!

约定优于配置(Convention Over Configuration), 也称作按约定编程是一种软件设计范式。目的在于减少软件开发人员所需要做出的决定的数量,从而获得简单的好处,而又不失去其中的灵活性。

  • Spring Cloud 是一个基于 Spring Boot 实现的服务治理工具包,在微服务架构中用于管理和协调服务。

微服务:就是把一个单体项目, 拆分为多个微服务, 每个微服务可以独立技术选型, 独立开发, 独立部署, 独立运维. 并且多个服务相互协调, 相互配合, 最终完成用户的价值.

其中 Spring Boot 是基于 Spring Framework 来构建的,Spring Cloud 是构建 Spring Boot 分布式环境。所以 Spring Boot 是中流砥柱,起到承上启下的作用:

但是注意:正是因为 SpringBoot 简化了开发,开箱即用,所以很多人都跳过了 Spring 的学习,学到后面这个注解那个类是什么都不知道。所以学习 SpringBoot 的前提是需要完全掌握 Spring 以及 SpringMVC 的知识的,不要急于求成,必须要一步一步扎实基础。

image

9 Spring 版本迭代

Spring 框架自从发布以来,就得到快速发展,经过时代的验证,现在已经是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。从 2004 发布的第一个 Spring 版本,到现在已经更新到第五个 Spring 版本了,我们下面来看看各个版本的变化。

image

(1) Spring 1. X

在 2004 年 3 月 24 日,Spring Framework 1.0 final 正式发布,Spring 1.0 当时只包含一个完整的项目,他把所有的功能都集中在一个项目中,其中包含了核心的 IOC、AOP,同时也包含了其它的诸多功能,例如:JDBC、Mail、ORM、事务、定时任务、Spring MVC 等等。由于 Spring 超前的眼光和博大的精神,在第一个版本的时候已经支持了很多第三方的框架,例如:Hibernate、ibatis、模板引擎等。所有自发布以来,Spring 框架迅速发展。但是此时的 Spring 只支持基于 XML 的配置。

(2) Spring 2. X

Spring 2.0 于 2006 年 10 月发布,到那时,Spring 的下载量已经超过了 100 万。Spring 2.0 中新增的特性有:具有可扩展的 XML 配置功能,用于简化 XML 配置,即对注解的支持,支持了基于注解的配置,支持 Java 5,额外的 IoC 容器扩展点,支持动态语言 (BeanShell)。

2007 年 11 月 Interface 21 公司更名为 SpringSource。同时发布了 Spring 2.5。 Spring 2.5 中的主要新功能包括支持 Java 6 和 Java EE 5,支持配置注释,支持自动检测和兼容组件的类路径和 OSGi 兼容 bundle。2007 年,SpringSource 从 benchmark capital 获得了 1000 万美元 A 轮投资。

2009 年 8 月,SpringSource 以 4.2 亿美元被 VMWare 收购,SpringSource 又在几周内收购了 cloud foundry,这是一家云 PaaS 供应商。

(3) Spring 3. X

Spring 3.0 于 2009 年 12 月发布,此时的 Spring 正式托管到 GitHub 上,我们可以 GitHub 的网站查看:GitHub - Spring-projects/Spring-framework: Spring Framework,Spring 3.0 增加许多重要特性,如重组模块系统,支持 Spring 表达式语言,基于 Java 的 bean 配置(JavaConfig),支持嵌入式数据库(如 HSQL,H 2 和 Derby),模型验证/ REST 支持和对 Java EE 的支持。

(4) Spring 4. X

2013 年 12 月,Pivotal 宣布发布 Spring 框架 4.0。Spring 4.0 是 Spring 框架的一大进步,它包含了对 Java 8 的全面支持,支持 Lambda 表达式的使用,更高的第三方库依赖性(groovy 1.8+,ehcache 2.1+,hibernate 3.6+等),提供了对@Scheduled 和@PropertySource 重复注解的支持,提供了空指针终结者 Optional,对核心容器进行增加:支持泛型的依赖注入、Map 的依赖注入、Lazy 延迟依赖的注入、List 注入、Condition 条件注解注入、对 CGLib 动态代理类进行了增强,对 groovy DSL for bean 定义支持,Spring MVC 基于 Servlet 3.0 开发,并且为了方便 Restful 开发,引入了新的 RestController 注解器注解,同时还增加了一个 AsyncRestTemplate 支持 Rest 客户端的异步无阻塞请求,对 websockets 的支持以及对泛型类型的支持作为注入 bean 的限定符。

(5) Spring 5. X

Spring 5.0 于 2017 年 9 月 28 日发布了通用版本 (GA)。Spring 5.0 开始支持 Java EE 7,同时兼容 JDK 9,但是 Spring 5 的运行环境最低要求是 Java 8 以上,全面支持 Servlet 3.1。其中新增的响应式编程是 SpringFramework 5.0 最重要的特性之一、WebFlux 框架 (全新的模块 Spring WebFlux 用于替代老的 Spring-webmvc)、对 Kotlin 也有了更好的支持等等。