Skip to content

Spring 全技术栈硬核学习指南:从入门到架构师级 ​

适用人群:有 Java 基础,想系统掌握 Spring 生态的开发者 技术版本:Spring Framework 6.x / Spring Boot 3.2.x / Spring Cloud 2023.x 阅读建议:按章节顺序递进,每章配动手实验 + 源码思考题


开篇:Spring 生态全景图与学习路径 ​

0.1 Spring 到底是什么? ​

很多人学了很久 Spring,却说不清它的本质。一句话总结:

Spring 是一个以 IoC(控制反转)和 AOP(面向切面编程)为内核,提供一站式企业级开发解决方案的轻量级 Java 开发框架。

它不是单一技术,而是一个大家族:

Spring 生态全景
├── 核心内核
│   ├── Spring Core:IoC、DI、Bean 生命周期
│   ├── Spring AOP:面向切面编程
│   └── Spring Expression Language(SpEL)
│
├── Web 层
│   ├── Spring MVC:传统 Servlet 栈 Web 框架
│   ├── Spring WebFlux:响应式 Web 框架
│   └── WebSocket / RSocket
│
├── 数据访问层
│   ├── Spring JDBC / JdbcTemplate
│   ├── Spring Transaction:声明式事务
│   ├── Spring Data:统一数据访问抽象(JPA/Mongo/Redis/ES)
│   └── ORM 整合:MyBatis、Hibernate
│
├── 安全与认证
│   ├── Spring Security:认证授权框架
│   └── Spring Security OAuth2 / SSO
│
├── 微服务生态(Spring Cloud)
│   ├── 注册中心:Nacos / Eureka / Consul
│   ├── 配置中心:Nacos Config / Spring Cloud Config
│   ├── 网关:Spring Cloud Gateway
│   ├── 服务调用:OpenFeign / RestTemplate
│   ├── 熔断降级:Sentinel / Resilience4j
│   ├── 链路追踪:Sleuth + Zipkin / SkyWalking
│   └── 分布式事务:Seata
│
├── 工程化加速
│   ├── Spring Boot:自动配置、起步依赖
│   ├── Spring Boot Actuator:应用监控
│   └── Spring Boot DevTools:开发热部署
│
├── 响应式与云原生
│   ├── Project Reactor:响应式编程基础
│   ├── Spring Cloud Stream:消息驱动
│   ├── Spring Cloud Function:函数式编程
│   └── Spring Native / GraalVM:原生镜像
│
└── 测试与集成
    ├── Spring Test:单元/集成测试
    ├── MockMvc:Web 层测试
    └── Testcontainers:容器化测试

0.2 四层学习路径(从入门到架构师) ​

层级核心目标掌握程度
L1 入门应用层会用 Spring Boot 做 CRUD 项目能写业务代码,知道注解怎么用
L2 原理理解层理解 IoC、AOP、自动配置原理能说清工作机制,排查常见问题
L3 生态整合层掌握微服务全栈、安全、数据访问能独立搭建完整后端系统
L4 架构源码层读源码、懂设计、做选型、调性能能做技术选型、架构设计、性能优化

💡 学习心法:先用起来,再挖原理,最后横向对比。不要一上来就死磕源码,先写够 1 万行业务代码,再看源码事半功倍。


第一部分:Spring Core 核心内核(地基篇) ​

1.1 IoC 与 DI:控制反转与依赖注入 ​

1.1.1 核心思想 ​

  • 控制反转(IoC):把对象创建、依赖管理的控制权,从业务代码手里交给 Spring 容器。
  • 依赖注入(DI):IoC 的具体实现方式,容器主动把依赖对象注入到需要的地方。

通俗类比: 传统写法 = 你自己去超市买菜、洗菜、做饭(全程自己控制) IoC = 点外卖,餐厅(Spring 容器)做好给你送过来,你只管吃(只管业务逻辑)

1.1.2 三种注入方式深度对比 ​

注入方式写法优点缺点适用场景
字段注入@Autowired 加在字段上代码最少,最简洁无法注入 final 字段、测试不友好、循环依赖隐蔽快速开发、Demo
Setter 注入@Autowired 加在 setter 方法上支持可选依赖、可重新注入对象可能处于不完整状态可选依赖、可变依赖
构造器注入构造方法传参Spring 官方推荐、依赖不可变、保证对象完整、测试友好依赖多时代码冗长生产环境、强制依赖

✅ 企业级最佳实践:强制依赖用构造器注入,可选依赖用 Setter 注入。字段注入只在 Demo 里用,生产代码不推荐。

1.1.3 Bean 的作用域 ​

作用域说明注意点
singleton(默认)单例,容器中只有一个实例不是线程安全的,不要在单例 Bean 里存可变成员变量
prototype多例,每次获取都创建新对象销毁方法 Spring 不负责调用,要自己处理
requestWeb 环境,每个请求一个实例仅 Web 应用可用
session每个会话一个实例仅 Web 应用可用
application整个 ServletContext 一个实例仅 Web 应用可用

🎯 面试高频:单例 Bean 线程安全吗? 答:Spring 不保证单例 Bean 的线程安全。如果 Bean 里有可变成员变量,并发场景下会有线程安全问题。解决:尽量用无状态 Bean(只存方法不存状态),必要时用 ThreadLocal、加锁或改成 prototype。

1.2 Bean 生命周期(硬核原理) ​

Bean 从创建到销毁,完整经历 10+ 个步骤,这是 Spring 扩展性的核心:

实例化 → 属性填充 → 初始化前 → 初始化 → 初始化后 → 就绪 → 销毁
          ↑          ↑          ↑
        依赖注入  BeanPostProcessor 扩展点

完整生命周期拆解 ​

  1. 实例化:调用构造方法创建 Bean 对象
  2. 属性填充:注入依赖(DI)
  3. Aware 接口回调:注入容器基础设施(BeanNameAware、BeanFactoryAware、ApplicationContextAware)
  4. BeanPostProcessor 前置处理:postProcessBeforeInitialization
  5. 初始化方法:
    • @PostConstruct 注解
    • InitializingBean 接口
    • init-method XML/注解配置
  6. BeanPostProcessor 后置处理:postProcessAfterInitialization(AOP 代理就在这里生成)
  7. Bean 就绪可用
  8. 销毁方法:
    • @PreDestroy 注解
    • DisposableBean 接口
    • destroy-method 配置

🔍 源码思考题:为什么 AOP 代理要在后置处理器里生成? 答:因为要等 Bean 初始化完成后,才能确定最终的对象状态,然后用动态代理(JDK/CGLIB)包装一层,把切面逻辑织入进去。

1.3 AOP 面向切面编程 ​

1.3.1 核心概念 ​

  • 切面(Aspect):横切逻辑的封装(比如日志、事务、权限)
  • 连接点(JoinPoint):可以被切入的方法
  • 切入点(Pointcut):实际要切入的哪些方法
  • 通知(Advice):切入的时机和逻辑(前置、后置、环绕、异常、最终)
  • 织入(Weaving):把切面逻辑插入目标方法的过程

1.3.2 两种动态代理对比 ​

代理方式实现原理适用条件性能
JDK 动态代理基于接口,生成实现类的代理对象目标类必须实现接口启动快,运行稍慢
CGLIB 动态代理基于继承,生成子类代理对象目标类不能是 final启动慢,运行快

Spring Boot 2.x 之后默认策略:

  • 有接口用 JDK 动态代理
  • 没接口用 CGLIB
  • 可以通过 spring.aop.proxy-target-class=true 强制 CGLIB

1.3.3 五种通知类型 ​

通知类型执行时机常用场景
@Before方法执行前权限校验、参数校验
@AfterReturning方法正常返回后返回值处理、日志记录
@AfterThrowing方法抛出异常后异常日志、告警通知
@After方法执行完(无论成功失败)资源清理
@Around环绕整个方法性能统计、事务控制(最强大)

💡 实用技巧:做性能监控用 @Around,统计接口耗时;做异常告警用 @AfterThrowing,捕获异常发通知。

1.4 Spring 事务管理 ​

1.4.1 事务传播行为(7 种) ​

这是面试必考题,也是业务开发中最容易踩坑的地方:

传播行为说明适用场景
REQUIRED(默认)有事务就加入,没有就新建绝大多数场景
REQUIRES_NEW不管有没有,都新建事务日志记录、独立事务
SUPPORTS有事务就加入,没有就非事务执行查询方法
NOT_SUPPORTED挂起当前事务,非事务执行不需要事务的操作
MANDATORY必须有事务,没有就抛异常强制事务环境
NEVER必须没有事务,有就抛异常禁止事务场景
NESTED嵌套事务,保存点机制子事务独立回滚

🚩 经典坑点:同一个类里方法调用,事务不生效! 原因:Spring 事务基于 AOP 代理,同类调用走的是原始对象,不走代理对象。 解决:注入自己、用 AopContext、拆到不同类里。

1.4.2 事务失效的 8 种场景 ​

  1. 方法不是 public
  2. 同类方法调用(this 调用)
  3. 异常被 try-catch 吃掉了
  4. 抛出的异常不是 RuntimeException
  5. 数据库引擎不支持事务(MyISAM)
  6. 传播行为配置错了
  7. 多线程环境下事务不生效
  8. 没有被 Spring 管理(自己 new 的对象)

第二部分:Spring Boot 工程化与自动配置 ​

2.1 Spring Boot 核心思想 ​

约定优于配置(Convention over Configuration):提供一套默认约定,你按约定来就不用写配置,特殊需求再自定义。

Spring Boot 四大核心:

  1. 起步依赖(Starter):把一组相关依赖打包,不用自己拼版本
  2. 自动配置:根据依赖自动装配 Bean
  3. 内嵌容器:Tomcat/Jetty/Undertow 内嵌,不用打 WAR
  4. Actuator 监控:开箱即用的应用监控端点

2.2 自动配置原理(源码级深入) ​

2.2.1 核心流程 ​

@SpringBootApplication
    ↓
@EnableAutoConfiguration
    ↓
@Import(AutoConfigurationImportSelector.class)
    ↓
读取 spring.factories / spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
    ↓
过滤 @Conditional 条件
    ↓
自动装配 Bean 到容器

2.2.2 常用条件注解 ​

注解作用
@ConditionalOnClass类路径下有指定类才生效
@ConditionalOnMissingBean容器中没有指定 Bean 才生效
@ConditionalOnProperty配置文件有指定属性才生效
@ConditionalOnWebApplicationWeb 环境才生效
@ConditionalOnJava指定 JDK 版本才生效

🔍 设计精髓:自动配置是"兜底"的。你自己配了 Bean,自动配置就退下;你没配,它才补上。这就是 @ConditionalOnMissingBean 的意义。

2.3 自定义 Starter ​

学会写 Starter,才算真正理解 Spring Boot。一个标准 Starter 包含:

  1. 自动配置类:定义 Bean 的创建逻辑
  2. 配置属性类:绑定配置文件参数
  3. spring.factories:注册自动配置类
  4. pom 依赖:打包相关依赖

💡 企业实战:公司内部通用组件、中间件封装,都做成自定义 Starter,各项目直接引入,开箱即用。

2.4 配置体系深度解析 ​

2.4.1 配置优先级(从高到低) ​

  1. 命令行参数
  2. ServletConfig 初始化参数
  3. ServletContext 初始化参数
  4. java:comp/env JNDI 属性
  5. JVM 系统属性(-D 参数)
  6. 操作系统环境变量
  7. jar 包外的 application-{profile}.yml
  8. jar 包内的 application-{profile}.yml
  9. jar 包外的 application.yml
  10. jar 包内的 application.yml
  11. @PropertySource 加载的配置
  12. Spring 内置默认值

🎯 面试题:配置文件放哪里优先级最高? 答:jar 包外面的 config 目录下 > jar 包外根目录 > jar 包内 config 目录 > jar 包内根目录。

2.4.2 三种配置读取方式对比 ​

方式特点适用场景
@Value单个注入,支持 SpEL少量零散配置
Environment动态获取,支持默认值工具类、动态 key
@ConfigurationProperties批量绑定、支持松散绑定、JSR303 校验一组相关配置(企业首选)

第三部分:Web 开发全解 ​

3.1 Spring MVC 工作原理 ​

3.1.1 核心组件与请求流程 ​

请求 → DispatcherServlet
    → HandlerMapping:找到对应 Controller 方法
    → HandlerAdapter:适配调用方法
    → Controller 执行业务
    → ModelAndView 返回
    → ViewResolver:解析视图
    → View 渲染
    → 响应返回

3.1.2 常用注解分类 ​

  • 请求映射:@RequestMapping、@GetMapping、@PostMapping
  • 参数接收:@RequestParam、@PathVariable、@RequestBody、@RequestHeader
  • 响应控制:@ResponseBody、@ResponseStatus
  • REST 风格:@RestController、@RestControllerAdvice

3.2 静态资源与 WebMvcConfigurer ​

3.2.1 静态资源默认位置 ​

META-INF/resources/ > resources/ > static/ > public/

3.2.2 WebMvcConfigurer 常用配置 ​

  • 静态资源映射:addResourceHandlers
  • 拦截器注册:addInterceptors
  • 跨域配置:addCorsMappings
  • 视图控制器:addViewControllers
  • 消息转换器:configureMessageConverters

⚠️ 重要提醒:99% 的场景用 WebMvcConfigurer 扩展,不要加 @EnableWebMvc,加了自动配置全失效。

3.3 拦截器 vs 过滤器 ​

对比维度Filter(过滤器)Interceptor(拦截器)
规范Servlet 规范Spring MVC 规范
执行时机进入 Servlet 之前进入 Controller 之前
粒度URL 级别方法级别
能否获取方法信息不能能(HandlerMethod)
能否访问 Spring 容器不能能
执行顺序Filter → Interceptor → Controller

3.4 全局异常处理 ​

3.4.1 三种异常处理方式 ​

  1. @ExceptionHandler:单个 Controller 内有效
  2. @ControllerAdvice + @ExceptionHandler:全局异常处理(最常用)
  3. HandlerExceptionResolver:底层自定义异常解析器

3.4.2 企业级异常处理架构 ​

异常分层体系
├── 业务异常(BizException):预期内的业务错误,返回具体提示
├── 参数校验异常(ValidationException):参数不合法,返回字段错误
├── 权限异常(AuthException):未登录/无权限,返回 401/403
└── 系统异常(Exception):兜底,返回通用提示,打 error 日志

✅ 最佳实践:异常信息对内打全栈日志,对外只返回友好提示,不要把堆栈暴露给前端。

3.5 参数校验(JSR-303) ​

3.5.1 常用校验注解 ​

  • @NotNull、@NotBlank、@NotEmpty
  • @Min、@Max、@Size
  • @Email、@Pattern
  • @Valid、@Validated(分组校验)

3.5.2 分组校验 ​

同一个 DTO 在新增和编辑场景校验规则不同,用分组校验:

public interface AddGroup {}
public interface UpdateGroup {}

public class UserDTO {
    @Null(groups = AddGroup.class, message = "新增时ID必须为空")
    @NotNull(groups = UpdateGroup.class, message = "修改时ID不能为空")
    private Long id;
}

第四部分:数据访问层全景 ​

4.1 Spring 事务深度解析 ​

4.1.1 事务隔离级别 ​

隔离级别脏读不可重复读幻读
READ_UNCOMMITTED✅✅✅
READ_COMMITTED❌✅✅
REPEATABLE_READ❌❌✅(MySQL 间隙锁解决)
SERIALIZABLE❌❌❌

MySQL InnoDB 默认是 REPEATABLE_READ。

4.1.2 分布式事务方案对比 ​

方案原理一致性性能适用场景
Seata AT两阶段提交,自动生成回滚 SQL最终一致较好大多数业务场景
TCCTry-Confirm-Cancel,业务代码实现最终一致好核心业务、性能要求高
Saga长事务,补偿机制最终一致好长链路业务
本地消息表本地事务 + 消息队列最终一致好异步解耦场景

4.2 MyBatis 整合与最佳实践 ​

4.2.1 三种开发方式 ​

  1. 注解版:@Select、@Insert 写在接口上(简单 SQL 适合)
  2. XML 版:SQL 写在 XML 文件里(复杂 SQL 首选)
  3. MyBatis-Plus:通用 CRUD 封装,单表不用写 SQL(企业开发神器)

4.2.2 分页方案对比 ​

方案优点缺点
PageHelper老牌插件,使用简单物理分页,多表关联容易出问题
MyBatis-Plus 分页和 MP 无缝集成,Lambda 写法依赖 MP
自己写 limit最灵活重复代码多

4.3 Spring Data JPA ​

JPA 是 ORM 标准,Hibernate 是实现。优点:单表 CRUD 不用写 SQL,面向对象;缺点:复杂 SQL 难优化,学习曲线陡。

🎯 选型建议:

  • 业务复杂、SQL 多变 → MyBatis / MyBatis-Plus
  • 业务简单、领域驱动、数据库无关 → Spring Data JPA

4.4 Redis 整合 ​

Spring Data Redis 提供了 RedisTemplate 和 StringRedisTemplate,常见场景:

  • 缓存:热点数据缓存、降低数据库压力
  • 计数器:点赞、浏览量
  • 分布式锁:SETNX + 过期时间
  • 排行榜:ZSet
  • 消息队列:List / PubSub

第五部分:Spring Security 安全框架 ​

5.1 核心概念 ​

  • 认证(Authentication):你是谁(登录)
  • 授权(Authorization):你能做什么(权限)
  • Principal:当前登录用户主体
  • GrantedAuthority:权限
  • SecurityContext:安全上下文,存认证信息

5.2 认证流程 ​

用户名密码 → UsernamePasswordAuthenticationFilter
    → AuthenticationManager 认证
    → UserDetailsService 加载用户信息
    → PasswordEncoder 校验密码
    → 认证成功:存入 SecurityContext
    → 认证失败:AuthenticationFailureHandler

5.3 权限控制方式 ​

  1. URL 级权限:配置类里配置 antMatchers().hasRole()
  2. 方法级权限:@PreAuthorize、@PostAuthorize 注解
  3. 页面级权限:Thymeleaf 安全标签

5.4 JWT 整合 ​

前后端分离项目主流方案:

  1. 登录成功生成 JWT Token 返回
  2. 前端每次请求带 Token
  3. 自定义过滤器解析 Token,设置认证信息
  4. Security 做权限校验

第六部分:Spring Cloud 微服务生态 ​

6.1 微服务核心组件 ​

功能主流选型
注册中心Nacos / Eureka / Consul
配置中心Nacos Config / Apollo / Spring Cloud Config
服务网关Spring Cloud Gateway / Zuul
服务调用OpenFeign / RestTemplate / Dubbo
熔断降级Sentinel / Resilience4j / Hystrix(停更)
链路追踪SkyWalking / Zipkin / Jaeger
分布式事务Seata

6.2 服务网关 Gateway ​

6.2.1 核心概念 ​

  • Route(路由):请求转发规则
  • Predicate(断言):匹配条件
  • Filter(过滤器):请求前后处理

6.2.2 网关作用 ​

  • 统一入口,对外暴露一个地址
  • 鉴权、限流、日志、跨域
  • 路由转发、负载均衡
  • 灰度发布、版本控制

6.3 服务熔断与降级 ​

6.3.1 为什么需要熔断? ​

服务雪崩:一个服务挂了,调用它的服务也跟着挂,连锁反应拖垮整个系统。

6.3.2 Sentinel 核心功能 ​

  • 流量控制:QPS、线程数限流
  • 熔断降级:慢调用、异常比例、异常数
  • 系统保护:CPU、负载、RT 系统级保护
  • 热点参数限流:针对热门参数限流

6.4 分布式链路追踪 ​

6.4.1 核心概念 ​

  • Trace:一次完整请求链路
  • Span:链路中的一个节点(一次调用)
  • TraceId:整条链路唯一 ID
  • SpanId:当前节点 ID

6.4.2 主流方案对比 ​

方案优点缺点
SkyWalking字节码注入,无侵入,UI 强大性能损耗稍大
Zipkin轻量,简单功能相对少
JaegerCNCF 毕业,云原生友好生态稍弱

第七部分:响应式编程与前沿技术 ​

7.1 响应式编程(Reactive) ​

7.1.1 核心思想 ​

异步非阻塞 + 数据流 + 背压。传统 Servlet 是一个请求一个线程,响应式是少量线程处理大量请求,适合 IO 密集型场景。

7.1.2 Reactor 两大类型 ​

  • Mono:0 或 1 个元素的流
  • Flux:0 或 N 个元素的流

7.1.3 Spring WebFlux ​

  • 异步非阻塞 Web 框架
  • 底层用 Netty,不是 Servlet 容器
  • 性能高,但开发调试难度大
  • 适用场景:高并发 IO 密集型、网关、推送服务

⚠️ 选型提醒:大多数业务系统还是 Spring MVC 更合适,开发效率高、生态成熟。不要为了用响应式而用响应式。

7.2 GraalVM 原生镜像(Spring Native) ​

  • 启动速度毫秒级
  • 内存占用极低
  • 无需 JRE 即可运行
  • 适合 Serverless、容器化部署
  • 缺点:构建慢、动态特性受限、调试困难

7.3 虚拟线程(Project Loom) ​

Java 21 正式支持虚拟线程,Spring Boot 3.2 完美支持。

  • 轻量级线程,百万级不是梦
  • 同步代码写出异步性能
  • 不用改代码,开个配置就生效
  • 比响应式编程友好太多

🔮 前沿展望:虚拟线程可能会让响应式编程的必要性大大降低。同步写法 + 虚拟线程,开发效率和性能兼得。

7.4 Spring AI ​

Spring 官方推出的 AI 开发框架,对接 OpenAI、通义千问、文心一言等大模型,提供统一抽象。

  • 对话接口统一
  • 向量数据库集成
  • Prompt 模板
  • 函数调用

第八部分:源码级设计模式与最佳实践 ​

8.1 Spring 中的经典设计模式 ​

模式应用场景
工厂模式BeanFactory、ApplicationContext 创建 Bean
单例模式单例 Bean
代理模式AOP 动态代理
模板方法JdbcTemplate、RestTemplate
观察者模式事件机制 ApplicationEvent
策略模式HandlerMapping、HandlerAdapter
装饰器模式BeanWrapper
责任链模式过滤器链、拦截器链

8.2 性能优化最佳实践 ​

  1. Bean 单例优先:尽量用单例,减少创建销毁开销
  2. 合理配置连接池:数据库连接池、HTTP 连接池
  3. 启用异步:@Async 异步处理耗时操作
  4. 缓存加持:Spring Cache + Redis
  5. 懒加载:非核心 Bean 用 @Lazy
  6. JVM 调优:堆内存、GC 策略
  7. 数据库优化:索引、SQL 优化、分库分表

8.3 代码规范与工程化 ​

  1. 分层架构:Controller → Service → DAO → DB
  2. DTO/DO/VO 分层,不要一个对象走天下
  3. 统一返回结果、统一异常处理
  4. 接口版本控制
  5. 日志规范:关键路径打日志,异常打全栈
  6. 单元测试 + 集成测试

第九部分:学习路线图与资源推荐 ​

9.1 三个月学习计划 ​

阶段时长核心任务
第 1 个月4 周Spring Boot 入门、Web 开发、MyBatis 整合、做一个 CRUD 项目
第 2 个月4 周IoC/AOP 原理、事务、安全框架、微服务基础组件
第 3 个月4 周源码阅读、性能优化、分布式方案、架构设计

9.2 推荐学习资源 ​

  • 官方文档:Spring 官方文档是最好的资料,没有之一
  • 源码:Spring 源码是最好的 Java 教科书
  • 书籍:《Spring 实战》、《Spring 技术内幕》、《Spring Boot 实战》
  • 实战:GitHub 找优秀开源项目模仿学习

9.3 给开发者的建议 ​

  1. 动手第一:看十遍不如写一遍,每个知识点都写 Demo 验证
  2. 追根溯源:遇到问题先想为什么,不满足于"能用就行"
  3. 横向对比:同类技术对比着学,理解各自的适用场景
  4. 关注前沿:Spring 生态更新很快,保持学习
  5. 形成体系:零散的知识点没用,串成知识网才是竞争力

最后想说:Spring 生态庞大而优雅,它不是束缚你的框架,而是帮你专注业务的工具。理解它的设计哲学,比记住一百个注解更有价值。当你能站在设计者的角度思考"为什么这么实现"时,你就从使用者成长为架构师了。

需要我针对其中某一章节展开更详细的代码示例和实战项目吗?

基于 Vite 强力驱动 | 纯静态轻量托管