Spring 从入门到精通深度实战指南 ——第1章 Spring 框架概述与环境搭建
1. 学习目标
通过本章学习,你将能够:
- 理解 Spring 框架的诞生背景、核心设计理念与生态体系
- 掌握 Spring Framework 6.x 的核心升级特性及其对开发的影响
- 独立搭建基于 JDK 21 + Maven + IntelliJ IDEA 的 Spring 开发环境
- 创建并运行第一个基于全注解配置的 Spring 程序
2. 核心概念
2.1 Spring 框架的诞生与发展历程
2002 年,Rod Johnson 在《Expert One-on-One J2EE Design and Development》一书中,首次质疑了当时 EJB(Enterprise JavaBeans)的复杂性和重量级设计。他指出,企业级 Java 开发并不需要 EJB 的繁重容器,使用普通的 Java 对象(POJO)配合轻量级依赖注入,就能构建出同样强大的企业应用。
2003 年,Rod Johnson 与 Juergen Hoeller 等人基于书中的理念,正式发布了 Spring Framework 1.0。Spring 的核心理念可以概括为:
“让 Java 开发变得更简单” —— 通过 IOC(控制反转)和 AOP(面向切面编程)两大核心技术,Spring 将开发者从复杂的 EJB 容器、JNDI 查找、冗长的 XML 配置中解放出来。
Spring 版本演进的关键节点:
| 版本 | 发布时间 | 里程碑特性 |
|---|---|---|
| Spring 1.0 | 2004.03 | IoC 容器、AOP 支持、JDBC 模板 |
| Spring 2.0 | 2006.10 | XML Schema 配置、注解支持、AspectJ 集成 |
| Spring 2.5 | 2007.11 | @Autowired、@Component 注解驱动开发 |
| Spring 3.0 | 2009.12 | JavaConfig、@Configuration、SpEL 表达式 |
| Spring 4.0 | 2013.12 | Java 8 全面支持、@RestController、WebSocket |
| Spring 5.0 | 2017.09 | 响应式编程(WebFlux)、Java 9+ 支持 |
| Spring 6.0 | 2022.11 | Java 17+ 基线、Jakarta EE 9+、AOT 编译、虚拟线程预备 |
| Spring 6.2 | 2024.11 | @Fallback Bean、后台初始化、AssertJ 集成、SpEL 增强 |
2.2 Spring 生态体系全景图
Spring 早已不只是一个框架,而是一个庞大的生态系统。理解这个全景图,才能知道在什么场景下使用什么组件:
┌─────────────────────────────────────────────────────────────┐
│ Spring 生态全景图 │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Spring Boot │ │ Spring Cloud │ │ Spring AI │ │
│ │ 快速开发 │ │ 微服务治理 │ │ AI 集成 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴─────────────────┴───────┐ │
│ │ Spring Framework 核心 │ │
│ │ IoC Container · AOP · Beans · Context · SpEL │ │
│ └──────┬───────────────────────────────────────────┘ │
│ │ │
│ ┌──────┴───────────────────────────────────────────┐ │
│ │ Spring Data (JPA · JDBC · Redis · MongoDB · ...) │ │
│ │ Spring Security (认证 · 授权 · OAuth2) │ │
│ │ Spring MVC / WebFlux (Web 开发) │ │
│ │ Spring Batch (批处理) · Spring Integration (集成) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Spring Framework:整个生态的基石,提供 IoC 容器、AOP、数据访问等核心能力。
Spring Boot:在 Framework 之上,通过"约定优于配置"和自动配置,让开发者可以快速创建独立运行的生产级应用。Spring Boot 不是替代 Spring Framework,而是对它的封装和增强。
Spring Cloud:基于 Spring Boot 构建的微服务解决方案,提供服务发现、配置中心、网关、熔断等分布式系统能力。
Spring Data:数据访问层抽象,统一了关系型数据库(JPA/JDBC)、NoSQL(Redis/MongoDB)、搜索引擎(Elasticsearch)的访问方式。
Spring Security:认证和授权框架,是 Java 生态中最强大的安全框架。
Spring AI(2024 年新项目):将 AI 能力集成到 Spring 应用中,支持向量数据库、提示工程、工具调用等。
2.3 Spring Framework 6.x 核心升级特性
Spring 6.x 是一次跨越式的版本升级,以下是必须了解的核心变化:
2.3.1 Java 17+ 基线要求
Spring 6.x 最低要求 Java 17,这意味着:
- 可以使用 Records、Sealed Classes、Pattern Matching、Text Blocks 等现代 Java 特性
- 不再兼容 Java 8/11,老项目迁移需要升级 JDK
// Java 17 Record 类在 Spring 中的使用
public record UserDTO(Long id, String name, String email) {
// 紧凑构造器进行校验
public UserDTO {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("name 不能为空");
}
}
}
2.3.2 Jakarta EE 9+ 命名空间迁移
最大 Breaking Change:javax.* 全部迁移到 jakarta.*:
// Spring 5.x (旧)
import javax.servlet.http.HttpServlet;
import javax.persistence.Entity;
import javax.annotation.PostConstruct;
// Spring 6.x (新)
import jakarta.servlet.http.HttpServlet;
import jakarta.persistence.Entity;
import jakarta.annotation.PostConstruct;
如果你使用的是 Spring Boot 3.x,它会自动处理这个迁移。但如果你的项目中有直接依赖 javax.* 的第三方库,需要升级或替换。
2.3.3 AOT 编译与原生镜像
AOT(Ahead-Of-Time)编译允许在构建时预处理 Spring 的反射、代理等动态行为,使应用可以编译为 GraalVM 原生镜像:
- 启动速度:从秒级降到毫秒级(< 100ms)
- 内存占用:减少 50-70%
- 适用场景:Serverless、容器化部署、微服务
2.3.4 虚拟线程(Virtual Threads)
Spring 6.1+ 支持 Java 21 的虚拟线程,在高并发场景下大幅提升吞吐量:
@Configuration
public class VirtualThreadConfig {
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
}
}
2.3.5 @Fallback Bean(Spring 6.2 新增)
当主 Bean 不可用时,自动切换到备选 Bean:
@Configuration
public class FallbackConfig {
@Bean
public PaymentService primaryPaymentService() {
return new AlipayService(); // 主支付服务
}
@Bean
@Fallback
public PaymentService fallbackPaymentService() {
return new WechatPayService(); // 备选支付服务
}
}
2.4 Spring 模块化架构深入解析
Spring Framework 本身由约 20 个模块组成,按功能分为六组:
核心容器(Core Container)
- spring-core:框架的基础工具类,包括反射、IO、类型转换等
- spring-beans:Bean 的创建、管理和依赖注入,BeanFactory 接口
- spring-context:ApplicationContext,在 BeanFactory 之上增加了国际化、事件传播、资源加载等
- spring-expression:SpEL(Spring Expression Language)表达式语言
AOP 与 Instrumentation
- spring-aop:基于代理的 AOP 实现
- spring-aspects:与 AspectJ 的集成
- spring-instrument:类加载时织入支持
数据访问(Data Access)
- spring-jdbc:JDBC 抽象层,JdbcTemplate
- spring-orm:ORM 框架集成(Hibernate、JPA)
- spring-tx:声明式和编程式事务管理
- spring-jms:JMS 消息集成
Web 层
- spring-web:基础的 Web 功能(文件上传、Web 工具类)
- spring-webmvc:Spring MVC 框架
- spring-webflux:响应式 Web 框架
- spring-websocket:WebSocket 支持
测试
- spring-test:集成测试支持(JUnit/Mockito 集成)
2.5 开发环境搭建
2.5.1 安装 JDK 21
# macOS 使用 Homebrew 安装
brew install openjdk@21
# 验证安装
java -version
# 输出:openjdk version "21.0.x" ...
# 配置环境变量(~/.zshrc)
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH="$JAVA_HOME/bin:$PATH"
2.5.2 安装 Maven
# macOS 安装
brew install maven
# 验证
mvn -v
# 输出:Apache Maven 3.9.x ...
2.5.3 Maven 配置优化
编辑 ~/.m2/settings.xml:
<settings>
<!-- 阿里云镜像加速 -->
<mirrors>
<mirror>
<id>aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Aliyun Maven Mirror</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
<!-- JDK 21 编译配置 -->
<profiles>
<profile>
<id>jdk21</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.compilerVersion>21</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
</settings>
2.6 第一个 Spring 程序:Hello World 全注解版
2.6.1 创建 Maven 项目
<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-hello</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<java.version>21</java.version>
<spring.version>6.2.19</spring.version>
</properties>
<dependencies>
<!-- Spring Context(包含 beans, core, expression, aop) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.6.2 编写业务类
// src/main/java/com/example/service/MessageService.java
package com.example.service;
import org.springframework.stereotype.Service;
@Service // 标记为 Spring Bean
public class MessageService {
public String getMessage() {
return "Hello, Spring 6!";
}
}
// src/main/java/com/example/controller/MessageController.java
package com.example.controller;
import com.example.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component // 标记为 Spring 管理的组件
public class MessageController {
private final MessageService messageService;
// 构造器注入(推荐方式)
@Autowired
public MessageController(MessageService messageService) {
this.messageService = messageService;
}
public void printMessage() {
System.out.println(messageService.getMessage());
}
}
2.6.3 配置类
// src/main/java/com/example/config/AppConfig.java
package com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 标记为配置类
@ComponentScan("com.example") // 扫描 com.example 包下的所有组件
public class AppConfig {
// 配置类本身不需要写代码,注解已经完成了所有配置
}
2.6.4 启动类
// src/main/java/com/example/MainApplication.java
package com.example;
import com.example.config.AppConfig;
import com.example.controller.MessageController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApplication {
public static void main(String[] args) {
// 1. 创建 IoC 容器(基于注解配置)
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// 2. 从容器中获取 Bean
MessageController controller = context.getBean(MessageController.class);
// 3. 使用 Bean
controller.printMessage();
// 输出:Hello, Spring 6!
// 4. 关闭容器
context.close();
}
}
2.6.5 运行与验证
# 编译
mvn clean compile
# 运行
mvn exec:java -Dexec.mainClass="com.example.MainApplication"
# 输出:
# Hello, Spring 6!
2.7 程序启动流程分析
上面的代码背后发生了什么?让我们跟踪 Spring 容器启动的关键步骤:
1. AnnotationConfigApplicationContext(AppConfig.class)
└── 创建 IoC 容器实例
2. 容器读取 AppConfig 配置类
└── @Configuration 标记这是一个配置类
└── @ComponentScan("com.example") 触发包扫描
3. 包扫描过程
└── 扫描 com.example 包及子包下的所有 .class 文件
└── 发现 @Service 标记的 MessageService
└── 发现 @Component 标记的 MessageController
└── 为每个组件创建 BeanDefinition(Bean 的定义信息)
4. 实例化 Bean
└── 创建 MessageService 实例(无依赖,直接实例化)
└── 创建 MessageController 实例
└── 发现构造器上有 @Autowired,注入 MessageService 实例
5. 容器初始化完成
└── 所有单例 Bean 创建完毕,等待使用
6. context.getBean(MessageController.class)
└── 从容器缓存中取出已创建好的 MessageController 实例
7. context.close()
└── 销毁所有单例 Bean,释放资源
3. 常见陷阱
陷阱1:组件扫描路径不正确
// 错误:扫描路径写错了
@ComponentScan("com.exmaple") // 拼写错误
// 正确:确保扫描路径覆盖所有组件所在的包
@ComponentScan("com.example")
陷阱2:忘记添加 @Component 或其派生注解
// 错误:MessageService 没有被 Spring 管理
public class MessageService { } // 不会被扫描到!
// 正确:添加 @Service 注解
@Service
public class MessageService { }
陷阱3:Maven 依赖版本不兼容
<!-- 错误:混用 Spring 5.x 和 6.x 的依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.30</version> <!-- 这是 Spring 5,运行在 Java 8+ -->
</dependency>
4. 动手练习
- 基础练习:修改 MessageService,让它返回带有当前时间的消息,验证 Bean 是否正常工作。
- 进阶练习:添加一个 GreetingService Bean,注入到 MessageController 中,实现根据用户名称返回个性化问候语。
- 挑战练习:尝试使用 XML 配置方式(
ClassPathXmlApplicationContext)实现同样的功能,对比两种配置方式的差异。
5. 小结
本章我们从 Spring 的诞生背景出发,理解了 Spring 的核心理念:通过 IoC 和 AOP 简化 Java 开发。掌握了 Spring Framework 6.x 的四个核心升级特性(Java 17+、Jakarta EE、AOT、虚拟线程),并完成了第一个全注解 Spring 程序的开发。
关键知识点回顾:
- Spring 生态 = Framework + Boot + Cloud + Data + Security + AI
- Spring 6.x 最低要求 Java 17,使用
jakarta.*命名空间 @Configuration+@ComponentScan+@Component/@Service构成全注解开发的基础AnnotationConfigApplicationContext是注解驱动开发的容器入口
6. 面试实战题
题1:Spring 框架的核心特性是什么?
答案:Spring 的核心特性包括:
- IoC(控制反转):将对象的创建和管理权交给 Spring 容器,而不是由开发者手动 new 对象。通过 DI(依赖注入)实现对象之间的解耦。
- AOP(面向切面编程):将横切关注点(日志、事务、安全)从业务逻辑中分离,实现无侵入式增强。
- 模块化设计:Spring 由约 20 个模块组成,可以按需引入。
- 声明式事务:通过
@Transactional注解实现声明式事务管理,无需手动编写事务代码。 - 生态丰富:Spring Boot、Spring Cloud、Spring Security 等子项目覆盖了企业开发的方方面面。
题2:Spring 6.x 相比 Spring 5.x 有哪些重大变化?
答案:
- Java 17+ 基线:不再支持 Java 8/11,全面拥抱 Records、Sealed Classes 等特性。
- Jakarta EE 9+:
javax.*全部迁移到jakarta.*,这是最大的 Breaking Change。 - AOT 编译:支持 GraalVM 原生镜像,启动速度从秒级降到毫秒级。
- 虚拟线程:支持 Java 21 虚拟线程,高并发性能大幅提升。
- 移除旧 API:清理了大量过时的 API 和废弃代码,框架更精简。
- @Fallback Bean(6.2 新增):支持主 Bean 不可用时自动切换到备选 Bean。
题3:Spring 的模块化设计是怎样的?各模块的职责是什么?
答案:Spring 分为六大模块组:
- 核心容器(Core Container):spring-core(工具类)、spring-beans(Bean 工厂)、spring-context(应用上下文)、spring-expression(SpEL)
- AOP:spring-aop(代理 AOP)、spring-aspects(AspectJ 集成)
- 数据访问:spring-jdbc(JdbcTemplate)、spring-orm(ORM 集成)、spring-tx(事务管理)
- Web:spring-web(基础 Web)、spring-webmvc(MVC)、spring-webflux(响应式)
- 测试:spring-test(集成测试支持)
题4:@Configuration 和 @Component 有什么区别?
答案:
@Component是通用的组件注解,标记一个类为 Spring Bean。@Configuration是@Component的特殊形式,标记一个类为配置类,用于定义@Bean方法。- 关键区别:
@Configuration类中的@Bean方法会被 CGLIB 代理,确保单例 Bean 的方法调用始终返回同一个实例(Full 模式);而普通@Component类中的@Bean方法不会被代理(Lite 模式)。 - 最佳实践:配置类使用
@Configuration,业务组件使用@Service、@Repository、@Controller等。
题5:ApplicationContext 和 BeanFactory 的区别是什么?
答案:
| 特性 | BeanFactory | ApplicationContext |
|---|---|---|
| 定位 | 底层 IoC 容器接口 | 高级容器接口(继承 BeanFactory) |
| Bean 加载 | 延迟加载(使用时才创建) | 预加载(启动时创建所有单例 Bean) |
| 国际化 | 不支持 | 支持 MessageSource |
| 事件发布 | 不支持 | 支持 ApplicationEvent |
| 资源加载 | 不支持 | 支持 ResourceLoader |
| 使用场景 | 资源受限环境(如 Applet) | 几乎所有企业应用 |
扩展:ApplicationContext 在启动时预加载所有单例 Bean,可以尽早发现配置错误。BeanFactory 延迟加载适合内存敏感的场景,但现代开发中几乎都用 ApplicationContext。
来源引用:
更多推荐

所有评论(0)