这是《Spring Boot 与 Spring Cloud 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Spring 是 Java 企业级开发的事实标准框架。它解决的核心问题是:把对象创建、依赖组装、事务边界、配置管理、远程调用和通用工程问题,从业务代码中抽离出来,交给容器和框架处理。
Spring Boot 让 Spring 更容易启动和部署,Spring Cloud 让微服务治理有了一套可组合的生态。理解 Spring 的关键不是背注解,而是理解容器、Bean 生命周期、扩展点、自动装配和微服务治理边界。
1.1 没有 Spring 时如何写程序
手工组装对象:
public class OrderService {
private final OrderRepository repository;
private final InventoryClient inventoryClient;
private final PaymentClient paymentClient;
public OrderService(OrderRepository repository,
InventoryClient inventoryClient,
PaymentClient paymentClient) {
this.repository = repository;
this.inventoryClient = inventoryClient;
this.paymentClient = paymentClient;
}
}
手动创建:
DataSource dataSource = new HikariDataSource(config);
OrderRepository repository = new JdbcOrderRepository(dataSource);
InventoryClient inventoryClient = new InventoryHttpClient(client);
PaymentClient paymentClient = new PaymentGrpcClient(channel);
OrderService service = new OrderService(repository, inventoryClient, paymentClient);
问题:
- 对象创建逻辑分散;
- 依赖关系手工维护;
- 事务、监控、代理等通用能力重复实现;
- 测试替换困难;
- 生命周期难以统一管理。
Spring 的答案是把对象交给 IoC 容器统一管理。
1.2 IoC 与 DI
IoC(Inversion of Control)控制反转,指对象创建和依赖组装的控制权从应用代码转移到容器。
DI(Dependency Injection)依赖注入,是实现 IoC 的主要方式。
@Service
public class OrderService {
private final OrderRepository repository;
private final InventoryClient inventoryClient;
public OrderService(OrderRepository repository,
InventoryClient inventoryClient) {
this.repository = repository;
this.inventoryClient = inventoryClient;
}
}
Spring 负责:
- 扫描 Bean 定义;
- 构造对象;
- 注入依赖;
- 初始化回调;
- 管理作用域;
- 销毁回调。
1.3 Bean 是什么
Bean 是由 Spring 容器管理的对象。
常见定义方式:
@Configuration
public class AppConfig {
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
常见注解:
| 注解 | 说明 |
|---|---|
@Component |
通用组件 |
@Service |
业务服务 |
@Repository |
数据访问 |
@Controller |
Web 控制器 |
@Configuration |
配置类 |
@Bean |
方法级 Bean 定义 |
@Autowired |
注入依赖 |
@Qualifier |
指定候选 Bean |
@Primary |
优先候选 |
@Value |
注入配置 |
@Scope |
作用域 |
推荐使用构造器注入,原因:
- 依赖不可变;
- 必需依赖明确;
- 便于单元测试;
- 避免字段注入的隐藏依赖;
- 与 final 字段配合更好。
1.4 Spring 的模块全景
Spring Framework
|-- Core / Beans / Context
|-- AOP
|-- Transaction
|-- JDBC / ORM
|-- Web / WebMvc
|-- Messaging
+-- Test
Spring Boot
|-- Auto Configuration
|-- Starter
|-- Actuator
|-- Embedded Server
+-- Production Utilities
Spring Cloud
|-- Discovery
|-- Config
|-- Gateway
|-- Circuit Breaker
|-- Load Balancer
|-- Tracing
+-- Stream / Bus
| 模块 | 解决问题 |
|---|---|
| Core Container | Bean 管理、依赖注入、事件 |
| AOP | 横切逻辑模块化 |
| Transaction | 声明式事务 |
| Spring MVC | Web 与 REST |
| Spring Data | 数据访问抽象 |
| Spring Boot | 自动装配与工程简化 |
| Spring Cloud | 微服务治理 |
1.5 AOP
AOP(面向切面编程)把日志、事务、权限、监控、限流这类横切逻辑从业务方法中抽离。
概念:
| 概念 | 说明 |
|---|---|
| Joinpoint | 程序执行点,Spring 中通常是方法 |
| Pointcut | 哪些方法被拦截 |
| Advice | 拦截后执行的动作 |
| Aspect | 切面,Pointcut + Advice |
| Target | 被代理对象 |
| Proxy | 代理对象 |
示例:
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.order.service..*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
try {
return pjp.proceed();
} finally {
long cost = System.currentTimeMillis() - start;
System.out.printf("%s cost %dms%n", pjp.getSignature(), cost);
}
}
}
注意:Spring AOP 默认基于代理,因此:
- 同类内部调用不会经过代理;
- private 方法不能被拦截;
- final 方法可能无法代理;
- 代理对象和目标对象类型不同;
- 自调用事务失效是常见问题。
1.6 Spring Boot 的价值
没有 Spring Boot 时,需要:
- 手写大量 XML 或配置类;
- 引入兼容版本依赖;
- 配置 DispatcherServlet;
- 配置数据源和事务;
- 打 WAR 部署外部 Tomcat;
- 自建健康检查和监控端点。
Spring Boot 提供:
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
核心能力:
| 能力 | 说明 |
|---|---|
| Starter | 依赖聚合和版本管理 |
| Auto Configuration | 按条件自动装配 |
| Externalized Config | 多环境配置 |
| Embedded Server | 内嵌 Tomcat/Jetty/Undertow |
| Actuator | 健康检查和指标 |
| Dev Tools | 开发效率工具 |
| Test | 测试支持 |
1.7 Spring Cloud 微服务全景
单体架构:
Client -> Monolith -> Database
微服务架构:
Client
-> Gateway
-> Order Service -> MySQL
-> Product Service -> MySQL
-> Inventory Service -> Redis
-> Search Service -> Elasticsearch
Spring Cloud 常见组件:
| 问题 | 常用方案 |
|---|---|
| 服务注册发现 | Spring Cloud Netflix Eureka / Consul / Nacos |
| 配置管理 | Spring Cloud Config / Nacos |
| 网关 | Spring Cloud Gateway |
| 负载均衡 | Spring Cloud LoadBalancer |
| 熔断限流 | Resilience4j / Sentinel |
| 链路追踪 | Micrometer Tracing / OpenTelemetry |
| 消息 | Spring Cloud Stream / Kafka / RocketMQ |
微服务不是银弹,它同时带来:
- 分布式事务;
- 服务治理;
- 链路追踪;
- 发布编排;
- 数据一致性;
- 排障复杂度。
1.8 一个典型请求链路
HTTP Request
-> Gateway
-> Filter
-> Load Balancer
-> Order Controller
-> Order Service
-> Transaction Proxy
-> Repository
-> MySQL
-> Kafka Producer
-> HTTP Response
在这条链路中,Spring 提供的能力包括:
- URL 路由;
- 参数绑定;
- 校验;
- 权限拦截;
- 事务;
- 异常转换;
- 远程调用;
- 监控埋点。
1.9 学习 Spring 的路线
第一阶段:使用
- Bean 注入;
- REST 接口;
- 配置文件;
- 数据访问;
- 事务;
- 测试。
第二阶段:理解
- 容器启动;
- Bean 生命周期;
- 扩展点;
- 代理;
- 自动装配;
- 配置加载优先级。
第三阶段:工程化
- 统一异常;
- 日志规范;
- 链路追踪;
- 安全;
- 参数校验;
- 性能调优。
第四阶段:微服务治理
- 注册发现;
- 网关;
- 熔断降级;
- 分布式事务;
- 事件驱动;
- 服务网格边界。
本章小结
Spring 的核心是 IoC 容器和 AOP 代理。Spring Boot 通过 Starter 和自动装配降低工程成本,Spring Cloud 提供微服务治理组件。学习 Spring 要从 Bean 和依赖关系开始,再到事务与代理机制,最后进入自动装配、启动流程和生产治理。
思考题
- IoC 和 DI 的关系是什么?
- 为什么推荐构造器注入?
- Spring AOP 为什么会导致自调用事务失效?
- Spring Boot 自动装配解决了什么问题?
- 微服务化后,系统复杂度新增在哪里?