Spring 生态体系
Spring 生态体系 #
Java 后端开发核心框架,包含 Spring Framework、Spring Boot、Spring Cloud
📋 目录 #
- Spring核心
- Spring Boot
- Spring Cloud
- 常见面试问题
学习路径 #
Spring 核心概念 #
IoC 容器 #
传统开发:
对象 ← 直接创建 → 依赖对象
IoC开发:
对象 ← 容器注入 → 依赖对象
优势:
✅ 解耦
✅ 便于测试
✅ 配置灵活
Bean 生命周期 #
关键扩展点:
| 接口 | 用途 |
|---|---|
BeanPostProcessor |
前后置处理(AOP原理) |
BeanFactoryPostProcessor |
修改Bean定义 |
FactoryBean |
定制Bean创建逻辑 |
Aware |
注入Spring资源 |
依赖注入方式 #
| 方式 | 说明 | 推荐 |
|---|---|---|
| 构造器注入 | 通过构造函数注入 | ✅ 推荐-final字段 |
| Setter注入 | 通过setter方法注入 | 辅助注入 |
| 字段注入 | @Autowired直接注入 | ❌ 不推荐 |
示例:
// ✅ 推荐方式
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// ❌ 不推荐
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}
AOP 面向切面编程 #
核心概念 #
通知类型:
| 通知类型 | 执行时机 | 场景 |
|---|---|---|
@Around |
环绕 | 性能监控、参数修改 |
@Before |
前置 | 权限检查、日志记录 |
@After |
后置 | 资源释放、日志记录 |
@AfterReturning |
返回后 | 结果处理 |
@AfterThrowing |
异常后 | 异常处理 |
AOP 实现原理 #
// 动态代理
if (使用接口) {
return JDK动态代理; // implements interface
} else {
return CGLIB代理; // extends class
}
Spring MVC #
请求处理流程 #
核心组件:
| 组件 | 作用 |
|---|---|
DispatcherServlet |
前端控制器,统一处理请求 |
HandlerMapping |
请求映射,找Controller |
HandlerAdapter |
适配器,执行Controller |
ViewResolver |
视图解析器,返回视图 |
HandlerInterceptor |
拦截器,AOP实现 |
RESTful API #
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping
public List<User> list() {
// 查询列表
}
@GetMapping("/{id}")
public User get(@PathVariable Long id) {
// 查询单个
}
@PostMapping
public User create(@RequestBody User user) {
// 创建
}
@PutMapping("/{id}")
public User update(@PathVariable Long id, @RequestBody User user) {
// 更新
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
// 删除
}
}
Spring Boot #
自动装配原理 #
**条件装配:
| 注解 | 条件 |
|---|---|
@ConditionalOnClass |
类路径存在指定类 |
@ConditionalOnMissingBean |
容器中不存在指定Bean |
@ConditionalOnProperty |
配置属性匹配 |
@ConditionalOnWebApplication |
Web环境 |
常用注解 #
| 分类 | 注解 | 说明 |
|---|---|---|
| 组件 | @Component |
通用组件 |
| 配置 | @Configuration |
配置类 |
| Web | @RestController |
REST控制器 |
配置文件 #
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
port: 6379
password:
server:
port: 8080
servlet:
context-path: /api
logging:
level:
root: INFO
com.example: DEBUG
Starter 依赖 #
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Spring Cloud #
核心组件 #
服务注册与发现 #
# Nacos 配置
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
group: DEFAULT_GROUP
服务调用 #
// OpenFeign 声明式HTTP客户端
@FeignClient(name = "user-service", url = "http://localhost:8081")
public interface UserClient {
@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
@PostMapping("/api/users")
User createUser(@RequestBody User user);
}
// 使用
@Service
public class OrderService {
@Autowired
private UserClient userClient;
public Order createOrder(Long userId) {
User user = userClient.getUser(userId);
// 创建订单...
}
}
服务网关 #
# Spring Cloud Gateway 配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
配置中心 #
# 从配置中心读取配置
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
namespace: dev
group: DEFAULT_GROUP
shared-configs:
- dataId: mysql-config.yaml
group: COMMON
refresh: true
熔断降级 #
// Sentinel 熔断降级
@SentinelResource(
value = "getUser",
blockHandler = "handleBlock", // 限流降级
fallback = "handleException" // 异常降级
)
public User getUser(Long id) {
return userRepository.findById(id);
}
public User handleBlock(Long id, BlockException ex) {
return User.builder().name("限流降级").build();
}
public User handleException(Long id, Throwable ex) {
return User.builder().name("异常降级").build();
}
事务管理 #
声明式事务 #
@Service
@Transactional
public class OrderService {
@Transactional(
propagation = Propagation.REQUIRED, // 传播行为
isolation = Isolation.READ_COMMITTED, // 隔离级别
timeout = 30, // 超时时间
readOnly = false, // 只读
rollbackFor = Exception.class // 回滚异常
)
public void createOrder(Order order) {
// 业务逻辑
}
}
传播行为 #
| 传播行为 | 说明 |
|---|---|
REQUIRED |
默认,有则加入,无则创建 |
REQUIRES_NEW |
总是创建新事务 |
NESTED |
嵌套事务 |
SUPPORTS |
有则加入,无则非事务 |
NOT_SUPPORTED |
非事务方式执行 |
MANDATORY |
必须在事务中 |
NEVER |
非事务方式 |
隔离级别 #
| 隔离级别 | 说明 | 问题 |
|---|---|---|
DEFAULT |
数据库默认 | - |
READ_UNCOMMITTED |
读未提交 | 脏读 |
READ_COMMITTED |
读已提交 | 不可重复读 |
REPEATABLE_READ |
可重复读 | 幻读 |
SERIALIZABLE |
串行化 | 性能差 |
面试高频问题 #
Spring Core #
- IoC和DI的区别?
- Bean的作用域(Singleton、Prototype)?
- Bean的生命周期?
- @Autowired和@Resource的区别?
- 循环依赖如何解决?
AOP #
- AOP的核心概念?
- JDK动态代理vs CGLIB?
- Spring事务失效场景?
- @Transactional的属性?
Spring Boot #
- 自动装配原理?
- Starter的作用?
- 内嵌Tomcat原理?
- SpringApplication启动流程?
Spring Cloud #
- 注册中心选型?
- 服务调用方式对比?
- 网关的作用和实现?
- 配置中心实现原理?
面试题答案详解 #
Spring Core #
- IoC和DI的区别?
答案:
| 概念 | 说明 |
|---|---|
| IoC (Inversion of Control) | 控制反转,把对象创建权交给容器 |
| DI (Dependency Injection) | 依赖注入,IoC的实现方式 |
关系: IoC是思想,DI是实现。
示例:
// 传统方式(自己控制创建)
UserService userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImpl());
// IoC方式(容器注入)
@Service
public class UserServiceImpl {
private final UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao; // 依赖注入
}
}
- Bean的作用域(Singleton、Prototype)?
答案:
| 作用域 | 说明 |
|---|---|
| Singleton | 单例(默认),整个容器一个实例 |
| Prototype | 多例,每次get创建新实例 |
| Request | Web请求级别 |
| Session | Web会话级别 |
| Application | Web应用级别 |
Singleton vs Prototype对比:
| 对比 | Singleton | Prototype |
|---|---|---|
| 实例数 | 1个 | 多个 |
| 创建时机 | 容器启动 | 每次获取 |
| 适用场景 | 无状态 | 有状态 |
- Bean的生命周期?
答案:
关键扩展点:
- BeanPostProcessor: 前后置处理(AOP原理)
- BeanFactoryPostProcessor: 修改Bean定义
- FactoryBean: 定制Bean创建逻辑
- @Autowired和@Resource的区别?
答案:
| 对比 | @Autowired | @Resource |
|---|---|---|
| 来源 | Spring | JSR-250 |
| 注入方式 | ByType(默认) | ByName(默认) |
| 属性 | required | name、type |
| 更强大 | ❌ | ✅ |
// @Autowired
@Autowired
private UserService userService; // 默认按类型
@Autowired @Qualifier("userServiceImpl") // 指定名称
private UserService userService;
// @Resource
@Resource(name="userServiceImpl") // 默认按名称
private UserService userService;
- 循环依赖如何解决?
答案:
循环依赖场景:
A → B
B → A
Spring三级缓存解决:
| 缓存 | 说明 |
|---|---|
| singletonObjects | 完整Bean缓存 |
| earlySingletonObjects | 早期Bean引用(未完成属性赋值) |
| singletonFactories | Bean工厂(创建早期引用) |
流程:
1. A实例化,放入singletonFactories
2. A填充属性,发现依赖B
3. B实例化,填充属性,发现依赖A
4. B从singletonFactories获取A的早期引用
5. B完成初始化
6. A继续填充属性,B已存在
7. 都完成初始化
注意:
- 只能解决单例循环依赖
- 构造器注入无法解决(提前暴露不了对象)
AOP #
- AOP的核心概念?
答案:
| 概念 | 说明 |
|---|---|
| Aspect (切面) | 横切关注点的模块化 |
| JoinPoint (连接点) | 可以被拦截的点(方法调用等) |
| PointCut (切入点) | 实际被拦截的JoinPoint |
| Advice (通知) | 拦截后要做的事 |
| Weaving (织入) | 把Aspect应用到目标对象 |
通知类型:
| 类型 | 执行时机 |
|---|---|
| @Before | 前置 |
| @After | 后置(成功失败都执行) |
| @AfterReturning | 返回后 |
| @AfterThrowing | 异常后 |
| @Around | 环绕(最强大) |
- JDK动态代理vs CGLIB?
答案:
| 对比 | JDK动态代理 | CGLIB |
|---|---|---|
| 原理 | 反射,实现接口 | 继承父类,字节码 |
| 要求 | 必须实现接口 | 可以不实现 |
| Spring默认 | 有接口用 | 无接口用 |
| 性能 | 略高 | 略低 |
Spring选择策略:
// 目标类有接口 → JDK动态代理
// 目标类无接口 → CGLIB
// 强制使用CGLIB
@EnableAspectJAutoProxy(proxyTargetClass = true)
- Spring事务失效场景?
答案:
| 场景 | 原因 |
|---|---|
| 方法非public | AOP代理要求 |
| 同类方法调用 | this调用,不经过代理 |
| 异常被捕获 | 异常没抛出 |
| 数据库引擎不支持 | MyISAM不支持事务 |
| 异常不是RuntimeException/Error | 默认只回滚RuntimeException和Error |
| 类没被Spring管理 | 对象不是Bean |
常见错误示例:
@Service
public class UserService {
public void a() {
this.b(); // 失效!this调用不走代理
}
@Transactional
public void b() {
}
}
// 解决:注入自己,或用AopContext
@Autowired
private UserService self;
public void a() {
self.b(); // 走代理
}
- @Transactional的属性?
答案:
| 属性 | 说明 |
|---|---|
| propagation | 传播行为 |
| isolation | 隔离级别 |
| timeout | 超时时间 |
| readOnly | 只读事务优化 |
| rollbackFor | 哪些异常回滚 |
| noRollbackFor | 哪些异常不回滚 |
传播行为总结:
| 传播行为 | 说明 |
|---|---|
| REQUIRED | 有则加入,无则创建(默认) |
| REQUIRES_NEW | 总是创建新事务 |
| NESTED | 嵌套事务 |
| SUPPORTS | 有就用,没有也可以 |
| MANDATORY | 必须有事务,否则报错 |
| NOT_SUPPORTED | 挂起现有事务,非事务执行 |
| NEVER | 不能有事务,否则报错 |
Spring Boot #
- 自动装配原理?
答案:
核心流程:
条件装配:
@ConditionalOnClass // 类路径下有这个类
@ConditionalOnMissingBean // 容器中没有这个Bean
@ConditionalOnProperty // 配置属性匹配
@ConditionalOnWebApplication // Web应用
示例:
spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
- Starter的作用?
答案:
Starter = 依赖集合 + 自动配置
| Starter | 包含 |
|---|---|
| spring-boot-starter-web | Spring MVC + Tomcat + Jackson |
| spring-boot-starter-data-jpa | JPA + Hibernate + MySQL驱动 |
| spring-boot-starter-cache | 缓存支持 |
好处:
- 不用自己一个个找依赖
- 版本兼容
- 开箱即用
自定义Starter:
命名: xxx-spring-boot-starter
结构:
- META-INF/spring.factories
- AutoConfiguration
- 内嵌Tomcat原理?
答案:
关键点:
- Spring Boot直接嵌入Tomcat依赖
- 不是war包部署,而是Java main方法启动
- Tomcat变成一个类库运行
- SpringApplication启动流程?
答案:
Spring Cloud #
- 注册中心选型?
答案:
| 对比 | Eureka | Nacos | Consul | Zookeeper |
|---|---|---|---|---|
| CAP | AP | AP/CP | CP | CP |
| 健康检查 | Client Beat | TCP/HTTP/MySQL | Script | KeepAlive |
| 可用性 | 高 | 高 | 中 | 低 |
| 社区活跃度 | 停更 | 活跃 | 中 | 中 |
| 其他 | - | 配置中心 | 多数据中心 | 大数据生态 |
推荐: Nacos(注册中心+配置中心二合一)
- 服务调用方式对比?
答案:
| 方式 | 说明 |
|---|---|
| RestTemplate | HTTP客户端,手动调用 |
| OpenFeign | 声明式HTTP客户端,写接口就行 |
| WebClient | 响应式HTTP客户端 |
OpenFeign示例:
@FeignClient("user-service")
public interface UserClient {
@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
}
// 使用
@Autowired
private UserClient userClient;
User user = userClient.getUser(1L);
- 网关的作用和实现?
答案:
网关作用:
- 统一入口
- 路由转发
- 负载均衡
- 限流熔断
- 日志监控
- 认证授权
实现对比:
| 网关 | 特点 |
|---|---|
| Spring Cloud Gateway | 响应式、性能好、推荐 |
| Netflix Zuul 1.x | 同步阻塞、已过时 |
| Zuul 2.x | 异步非阻塞、国内少用 |
Gateway示例配置:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- 配置中心实现原理?
答案:
核心流程:
1. 应用启动,从配置中心拉取配置
2. 建立长连接监听配置变化
3. 配置变更时收到通知
4. 动态刷新@ConfigurationProperties的Bean
Nacos配置中心原理:
- 长连接 + HTTP回调
- MD5对比,只推送变更
- 本地缓存配置,断网可用
实现类:
// 刷新配置
@RefreshScope // 热刷新
@ConfigurationProperties
public class UserConfig {
}
🔗 相关笔记 #
最后更新: 2026-04-29