Spring 全家桶是目前 Java 开发必不可少的工具,随着开发技术的不断演进,Spring 框架也变得越来越复杂。今天简单梳理一下 Spring 框架的概念,目的是建立起一个更高维度的认识,这里不涉及具体的技术实现和代码逻辑。

我们打开 Spring 的官网,看到官方对 Spring 的介绍是:

Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world’s most popular Java framework.

官网还列出了 Spring 全家桶的主要功能:

What Spring can do?

可以看到,Spring 已经发展成为一个生态,覆盖了后端开发的方方面面。下面我们从 Spring 生态中最常用的三个框架入手,介绍 Spring 解决了哪些问题。

Spring Framework

Spring Framework 是 Spring 生态的基础。Spring 框架分为不同的模块(modules),应用可以任意选择需要的模块整合进自己的代码。下图是 Spring Framework 的模块概览:

Spring Framework 概览。Spring 框架一直在发展,建议从官方文档查看最新资料

从图中我们可以看出,Spring 框架的核心 core 模块是所有功能都需要依赖的,spring-core 模块主要提供了最基础的 IoC 容器,在此基础上 Spring 扩展大多数应用都会使用的公共模块,包括 AOP ,负责支持切面编程;Message,负责支持事件驱动等。Data Access 模块负责封装数据访问相关的功能,包括整合 ORM 框架,事务处理等;Web 模块负责处理 Web 开发相关的功能,提供了 Spring MVC 框架支持传统的同步 web 服务,和 Spring WebFlux 框架支持异步响应式编程。

从 Spring Framework 的模块来看,Spring Framework 涵盖了 Java 企业级应用开发的大部分功能模块。 它不关注开发中某块具体功能如何实现,它的定位是一个 Java 应用开发的大框架,用来协调应用各部分的工作。做个不怎么合适的对比,Spring 框架在单体应用中扮演的角色就像 Zookeeper 在分布式应用中扮演的角色。最核心的作用是 协调。Spring 协调的是各个具体功能模块,Zookeeper 协调的是各个具体的微服务。

Spring 框架如何实现协调的功能呢?最重要的技术就是 控制反转,也叫 依赖注入。这两个说的其实是一件事情,控制反转是一种设计思想,依赖注入是这种思想的一个实现。Spring 通过 IoC 容器协调各模块的工作。在 Spring 的代码中,IoC 容器被称为 ApplicationContext,业务上下文,也说明了其设计目的是统一协调整个业务。

Spring 框架另一个重要的概念是 AOP (Aspect Oriented Programming),面向切面编程。这是一种设计思想。OOPAOP 都是为了解耦,编写出更清晰可维护的代码。OOP 关注的是业务功能层面的封装,纵向解决类和方法层面的设计。AOP 关注的是公用业务的设计,从横向解决代码重复和耦合的问题。Spring 通过 JDK 代理和 AspectJ 代理支持 AOP。

Spring Framework 是 J2EE 的轻量级替代品,它提供了很多方便的功能:

  1. IoC 容器将对象之间的依赖关系交给 Spring 框架管理,降低各个组件之间的耦合性;
  2. 提供了很多公共服务,如事务管理、Message 等;
  3. 对 AOP 有很好的支持,方便切面编程;
  4. 对主流的框架提供了很好的集成支持,如 Hibernate、JPA等;
  5. DI 机制降低了业务对象替换的复杂性;
  6. 低侵入,对业务代码污染极低;
  7. 高度开放性,不强制依赖 Spring,开发者可以自由选择 Spring 的部分功能模块;

Spring Boot

有了 Spring Framework,为什么还要推出 Spring Boot?这两者有什么区别?要回答这个问题,我们首先看一下 Spring Framework 解决了什么问题,没有解决什么问题。

Spring 框架大大提高了开发的便利性,但人们逐渐发现,Spring 整合其他框架的过程中,产生了大量的配置文件。我们以开发普通的 web 应用为例,看看需要处理多少配置文件:

  • Spring IoC 容器配置文件和 AOP 配置;
  • 数据层 ORM 框架配置,如 MyBatis 或 Hibernate 的配置;
  • web 层的配置,如 Spring MVC 的配置;
  • servlet 的配置;
  • 日志配置;
  • ……

面向对象编程变成了面向配置编程。每次启动一个项目,都要编写大量配置文件,耗费大量的时间。虽然催生了很多脚手架项目,但维护起来总是不太方便的。

另外,由于应用整合了许多框架,各个框架对 Spring 又有不同程度的依赖,有些支持高版本的 Spring,有些支持低版本的 Spring,开发人员需要逐一确认依赖是否有冲突,费时费力。

基于这些问题,Spring Boot 应运而生了。Spring Boot 的特点就是:

  1. 开箱即用。无需处理繁琐的配置和混乱的依赖;
  2. 灵活配置。Spring Boot 自动整合了大量的开源框架,并且设定好了默认配置。开发人员也可以灵活修改;
  3. 提供了一些大型项目中常见的非功能特性,如嵌入式服务器、安全、指标、健康监测、外部配置等;

Spring Boot 的核心功能有两个:

  • 起步依赖。将具有某种功能的依赖打包到一起,并提供一些默认配置,开发人员只需要关注少量核心配置即可使用,极大地减少了开发的成本。
  • 自动配置。Spring Boot 内部实现了很多配置策略,在程序启动时,Spring Boot 根据各种条件和策略决定使用哪些配置,目的还是减少开发人员的成本;

从这里我们可以看出,Spring Boot 和 Spring Framework 的关注点不一样,这两者其实没有什么可比性。Spring Boot 是在 Spring Framework 的基础上,添加了一些应用层面的功能,解决开发人员的痛点。我们在 Spring Framework 章节里提到,它的核心作用就是协调,但它协调的代价就是你需要实现提供大量的配置告诉 Spring 怎么做。而 Spring Boot 则更近一步,变成了 自动协调,它遵循 约定大于配置 的理念,自动为其他模块添加相关配置。

Spring Boot 整合了相当多的组件,几乎涵盖了 web 开发和微服务开发的所有场景。具体可以看一下官网的介绍

Spring Cloud

Spring Cloud 关注的是分布式系统中各个服务之间的协调。

相比于单体服务关注的是服务内部各个模块之间的协调,分布式系统的核心的关注点是各个微服务之间如何有效协调沟通,统一提供一套高可用的整体服务。

Spring Cloud 架构

Spring Cloud 整合了一大批业内知名的微服务开发组件,其中主要包括:

模块 项目 说明
配置中心 Spring Cloud Config, Spring Cloud Consul, Spring Cloud Alibaba Nacos 使用 git 集中管理外部配置
服务发现 Netflix Eureka, Spring Cloud Spring Cloud Zookeeper, Etcd 默认使用 Netflix Eureka 支持
服务路由/负载均衡 Netflix Ribbon, Spring Cloud Loadbalancer  
消息总线 Spring Cloud Bus 集成了 RabbitMQ 和 Kafka
API 网关 Netflix Zuul, Spring Cloud Gateway  
服务治理 Netflix Hystrix, Sentinel, Resilience4j  
OSBAPI Spring Cloud Open Service Broker  

Spring Cloud 把分布式系统各个环节抽象成一个节点进行封装,允许开发人员灵活切换实现。

总结

这三个组件介绍完,我想可以提炼出 Spring 贯穿始终的设计思想了:Spring 致力于提供一套解决方案,适用于后端软件开发的各个层面。 Spring Framework 负责协调服务内部各个对象间的关系;Spring Boot 更近一步,站在对象组成的框架层面,负责协调各个框架灵活协作;Spring Cloud 再进一步,站在各个服务组成的分布式系统层面,负责协调各个服务之间的协作和管理。

这三个框架层层递进,在功能上各有关注点,互不冲突,组成了 Spring 的整个生态圈。