Spring Framework 概览 (Overview)
Spring 使得创建 Java 企业级应用程序变得简单。它提供了在企业级环境中使用 Java 语言所需的一切支持,同时支持 Groovy 和 Kotlin 作为 JVM 上的替代语言,并能够根据应用程序的需求灵活地创建多种架构。从 Spring Framework 6.0 开始,Spring 要求 Java 17 或更高版本。
Spring 支持广泛的应用场景。在大型企业中,应用程序通常存在很长时间,必须运行在升级周期超出开发人员控制的 JDK 和应用服务器上。其他的应用可能以单个 Jar 包的形式运行,内嵌服务器,可能部署在云环境中。还有一些可能是无需服务器的独立应用程序(如批处理或集成任务)。
Spring 是开源的。它拥有一个庞大且活跃的社区,基于各种真实的用例提供持续的反馈。这帮助 Spring 在很长一段时间内成功地演进。
1. 我们所说的 "Spring" 是指什么?
"Spring" 一词在不同的语境下代表不同的含义。它可以用来指代 Spring Framework 项目本身,这也是一切的起点。随着时间的推移,其他 Spring 项目也构建在 Spring Framework 之上。通常,当人们说 "Spring" 时,他们指的是整个 Spring 项目家族。本参考文档侧重于基础:即 Spring Framework 本身。
Spring Framework 被划分为多个模块。应用程序可以根据需要选择所需的模块。其核心是核心容器模块,包括配置模型和依赖注入机制。除此之外,Spring Framework 还为不同的应用架构提供基础支持,包括消息传递、事务数据与持久化以及 Web。它还包括基于 Servlet 的 Spring MVC Web 框架,以及与之并行的 Spring WebFlux 响应式 Web 框架。
关于模块的一点说明:Spring Framework 的 Jar 包支持部署到模块路径(Java Module System)。为了在启用模块的应用中使用,Spring Framework 的 Jar 包附带了 Automatic-Module-Name 清单条目,这些条目定义了稳定的语言级模块名称(如 spring.core、spring.context 等),独立于 Jar 制品名称。这些 Jar 包遵循相同的命名模式,只是用 - 代替了 . —— 例如 spring-core 和 spring-context。当然,Spring Framework 的 Jar 包在类路径(Classpath)上也能正常工作。
2. Spring 及其框架的历史
Spring 诞生于 2003 年,是为了应对早期 J2EE 规范的复杂性。虽然有些人认为 Java EE 及其现代继任者 Jakarta EE 与 Spring 是竞争关系,但实际上它们是互补的。Spring 编程模型并不全盘接受 Jakarta EE 平台规范;相反,它集成了传统 EE 伞状规范下选定的单个规范:
- Servlet API (JSR 340)
- WebSocket API (JSR 356)
- 并发实用工具 (JSR 236)
- JSON 绑定 API (JSR 367)
- Bean 校验 (JSR 303)
- JPA (JSR 338)
- JMS (JSR 914)
- 以及必要时用于事务协调的 JTA/JCA 设置。
Spring Framework 还支持依赖注入 (JSR 330) 和常见注解 (JSR 250) 规范,应用开发人员可以选择使用这些规范,而不是 Spring Framework 提供的 Spring 特定机制。最初,这些是基于通用的 javax 包。
从 Spring Framework 6.0 开始,Spring 已升级到 Jakarta EE 9 级别(例如 Servlet 5.0+、JPA 3.0+),基于 jakarta 命名空间,而不是传统的 javax 包。随着 EE 9 成为最低标准并已支持 EE 10,Spring 已准备好为 Jakarta EE API 的进一步演进提供开箱即用的支持。Spring Framework 6.0 与 Tomcat 10.1、Jetty 11 等 Web 服务器以及 Hibernate ORM 6.1 完全兼容。
随着时间的推移,Java/Jakarta EE 在应用开发中的角色发生了演变。在 J2EE 和 Spring 的早期阶段,应用程序被创建出来部署到应用服务器。今天,在 Spring Boot 的帮助下,应用程序以 DevOps 和云友好的方式创建,内嵌 Servlet 容器且易于更换。从 Spring Framework 5 开始,WebFlux 应用程序甚至不直接使用 Servlet API,并可以运行在非 Servlet 容器的服务器(如 Netty)上。
Spring 不断创新和发展。除了 Spring Framework,还有其他项目,如 Spring Boot、Spring Security、Spring Data、Spring Cloud、Spring Batch 等。请记住,每个项目都有自己的源代码库、问题追踪器和发布节奏。参见 spring.io/projects 以获取 Spring 项目的完整列表。
3. 设计哲学 (Design Philosophy)
在学习一个框架时,不仅要了解它能做什么,还要了解它遵循什么原则。以下是 Spring Framework 的指导原则:
- 在每个层面提供选择。Spring 允许你尽可能晚地推迟设计决策。例如,你可以通过配置切换持久化提供商,而无需更改代码。对于许多其他基础设施关注点和第三方 API 的集成也是如此。
- 容纳多样化的视角。Spring 拥抱灵活性,不对事情应该如何完成持有偏见(Non-opinionated)。它以不同的视角支持广泛的行业需求。
- 保持强劲的向后兼容性。Spring 的演进经过精心管理,在版本之间强制执行的破坏性更少。Spring 支持精心挑选的 JDK 版本和第三方库范围,以方便依赖于 Spring 的应用程序和库的维护。
- 关注 API 设计。Spring 团队投入大量思考和时间来制作直观的 API,并让这些 API 在许多版本和许多年份中经得起考验。
- 设定高标准的代码质量。Spring Framework 非常强调有意义、及时且准确的 Javadoc。它是为数不多的可以声称代码结构整洁且包之间没有循环依赖的项目之一。
4. 反馈与贡献
对于如何操作的问题或诊断、调试问题,我们建议使用 Stack Overflow。点击此处查看 Stack Overflow 上建议使用的标签列表。如果你非常确定 Spring Framework 中存在问题或想提出功能建议,请使用 GitHub Issues。
如果你有解决方案或建议的修复办法,可以在 GitHub 上提交拉取请求(Pull Request)。但是,请记住,对于除最琐碎的问题外的所有问题,我们都希望在问题追踪器中提交一个 Issue,以便进行讨论并为未来的参考留下记录。
更多详细信息,请参见 CONTRIBUTING 顶层项目页面上的指南。
5. 快速开始 (Getting Started)
如果你刚接触 Spring,你可能想通过创建一个基于 Spring Boot 的应用程序来开始使用 Spring Framework。Spring Boot 提供了一种快速(且“有主见”的)方式来创建生产就绪的基于 Spring 的应用程序。它基于 Spring Framework,倡导约定优于配置,旨在让你尽可能快地运行起来。
你可以使用 start.spring.io 来生成一个基础项目,或遵循某个“快速入门”指南,例如构建 RESTful Web 服务。这些指南除了更容易理解之外,也非常关注任务本身,且大多基于 Spring Boot。它们还涵盖了 Spring 家族中的其他项目,你在解决特定问题时可能需要考虑这些项目。
补充教学 —— 理解 Spring 6 的“分水岭”
1. 为什么是 Java 17? Spring 6 选择 Java 17 作为基准版本是一个重大决策。Java 17 是一个长期支持(LTS)版本,带来了密封类(Sealed Classes)、记录类(Records)等重要语法特性。更重要的是,它为 Spring 的虚拟线程(Project Loom)适配和AOT 编译打下了基础。如果你还在用 Java 8,那么你将无法升级到 Spring 6 或 Spring Boot 3。
2. jakarta 命名空间大迁移 这是开发者最容易“踩坑”的地方。历史上的 Java EE 由 Oracle 移交给 Eclipse 基金会后,改名为 Jakarta EE。由于商标限制,从 EE 9 开始,包名必须从 javax.* 更改为 jakarta.*。
- 影响:如果你升级到 Spring 6,所有的
import javax.servlet.*都必须改为import jakarta.servlet.*。这不仅仅是改个名字,意味着旧的第三方库如果不适配,将无法直接在 Spring 6 环境下工作。
3. “不持偏见” (Non-opinionated) vs “约定优于配置” (Convention over Configuration)
- Spring Framework 是“不持偏见”的:它提供了无限的可能性,你可以用 XML 配置,也可以用注解,或者编程式配置。它不会强制你必须怎么做。
- Spring Boot 是“有主见”的:它为了简化,帮你做了很多默认选择(Convention)。
- 总结:Spring Framework 给开发者控制权,Spring Boot 给开发者生产力。
4. 持续的 API 设计美感 如果你翻看 Spring 的源码,你会发现它的命名极其规范(虽然有时候名字很长,如 AnnotationConfigWebApplicationContext)。遵循这种命名和逻辑结构,不仅能帮你更好地理解 Spring,也能提升你自己的代码设计水平。