Spring 生态体系 #

Java 后端开发核心框架,包含 Spring Framework、Spring Boot、Spring Cloud


📋 目录 #


学习路径 #

IoC/DI

AOP

Spring MVC

Spring Boot

Spring Cloud


Spring 核心概念 #

IoC 容器 #

传统开发:
  对象 ← 直接创建 → 依赖对象

IoC开发:
  对象 ← 容器注入 → 依赖对象

优势:
  ✅ 解耦
  ✅ 便于测试
  ✅ 配置灵活

Bean 生命周期 #

实例化

属性赋值

BeanNameAware

BeanFactoryAware

ApplicationContextAware

BeanPostProcessor前置

InitializingBean

init-method

BeanPostProcessor后置

就绪

DisposableBean

destroy-method

销毁

关键扩展点:

接口 用途
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 面向切面编程 #

核心概念 #

切面 Aspect = 切入点 PointCut + 通知 Advice

切面 Aspect

切入点 PointCut: @annotation(LogAnnotation)

通知 Advice: @Around/@Before/@After...

应用到目标方法

通知类型:

通知类型 执行时机 场景
@Around 环绕 性能监控、参数修改
@Before 前置 权限检查、日志记录
@After 后置 资源释放、日志记录
@AfterReturning 返回后 结果处理
@AfterThrowing 异常后 异常处理

AOP 实现原理 #

// 动态代理
if (使用接口) {
    return JDK动态代理;    // implements interface
} else {
    return CGLIB代理;      // extends class
}

Spring MVC #

请求处理流程 #

请求

DispatcherServlet

HandlerMapping

HandlerAdapter

Controller

ViewResolver

Response

核心组件:

组件 作用
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 #

自动装配原理 #

@SpringBootApplication

@SpringBootConfiguration // 配置类

@EnableAutoConfiguration // 自动配置 ⭐

@ComponentScan // 组件扫描

AutoConfigurationImportSelector

读取 META-INF/spring.factories

加载所有自动配置类

**条件装配:

注解 条件
@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 #

核心组件 #

Spring Cloud 微服务架构

Infrastructure

Config
Nacos

Sentinel
限流

Sleuth
链路追踪

网关与发现

API Gateway
Gateway

Discovery
Nacos/Eureka

Service Instance

服务A

服务B

服务C

OpenFeign

Ribbon/LoadBalancer

服务注册与发现 #

# 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 #

  1. IoC和DI的区别?
  2. Bean的作用域(Singleton、Prototype)?
  3. Bean的生命周期?
  4. @Autowired和@Resource的区别?
  5. 循环依赖如何解决?

AOP #

  1. AOP的核心概念?
  2. JDK动态代理vs CGLIB?
  3. Spring事务失效场景?
  4. @Transactional的属性?

Spring Boot #

  1. 自动装配原理?
  2. Starter的作用?
  3. 内嵌Tomcat原理?
  4. SpringApplication启动流程?

Spring Cloud #

  1. 注册中心选型?
  2. 服务调用方式对比?
  3. 网关的作用和实现?
  4. 配置中心实现原理?

面试题答案详解 #

Spring Core #

  1. 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; // 依赖注入
    }
}

  1. Bean的作用域(Singleton、Prototype)?

答案:

作用域 说明
Singleton 单例(默认),整个容器一个实例
Prototype 多例,每次get创建新实例
Request Web请求级别
Session Web会话级别
Application Web应用级别

Singleton vs Prototype对比:

对比 Singleton Prototype
实例数 1个 多个
创建时机 容器启动 每次获取
适用场景 无状态 有状态

  1. Bean的生命周期?

答案:

实例化 Instantiation

属性赋值 Populate

BeanNameAware.setBeanName()

BeanFactoryAware.setBeanFactory()

ApplicationContextAware.setApplicationContext()

BeanPostProcessor.postProcessBeforeInitialization()

@PostConstruct / InitializingBean.afterPropertiesSet()

init-method

BeanPostProcessor.postProcessAfterInitialization()

Bean可用 Ready

@PreDestroy / DisposableBean.destroy()

destroy-method

Bean销毁 Destroyed

关键扩展点:

  • BeanPostProcessor: 前后置处理(AOP原理)
  • BeanFactoryPostProcessor: 修改Bean定义
  • FactoryBean: 定制Bean创建逻辑

  1. @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;

  1. 循环依赖如何解决?

答案:

循环依赖场景:

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 #

  1. AOP的核心概念?

答案:

概念 说明
Aspect (切面) 横切关注点的模块化
JoinPoint (连接点) 可以被拦截的点(方法调用等)
PointCut (切入点) 实际被拦截的JoinPoint
Advice (通知) 拦截后要做的事
Weaving (织入) 把Aspect应用到目标对象

通知类型:

类型 执行时机
@Before 前置
@After 后置(成功失败都执行)
@AfterReturning 返回后
@AfterThrowing 异常后
@Around 环绕(最强大)

  1. JDK动态代理vs CGLIB?

答案:

对比 JDK动态代理 CGLIB
原理 反射,实现接口 继承父类,字节码
要求 必须实现接口 可以不实现
Spring默认 有接口用 无接口用
性能 略高 略低

Spring选择策略:

// 目标类有接口 → JDK动态代理
// 目标类无接口 → CGLIB
// 强制使用CGLIB
@EnableAspectJAutoProxy(proxyTargetClass = true)

  1. 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(); // 走代理
}

  1. @Transactional的属性?

答案:

属性 说明
propagation 传播行为
isolation 隔离级别
timeout 超时时间
readOnly 只读事务优化
rollbackFor 哪些异常回滚
noRollbackFor 哪些异常不回滚

传播行为总结:

传播行为 说明
REQUIRED 有则加入,无则创建(默认)
REQUIRES_NEW 总是创建新事务
NESTED 嵌套事务
SUPPORTS 有就用,没有也可以
MANDATORY 必须有事务,否则报错
NOT_SUPPORTED 挂起现有事务,非事务执行
NEVER 不能有事务,否则报错

Spring Boot #

  1. 自动装配原理?

答案:

核心流程:

@SpringBootApplication

@SpringBootConfiguration

@EnableAutoConfiguration ⭐

@ComponentScan

@Import(AutoConfigurationImportSelector)

读取 META-INF/spring.factories

加载自动配置类

条件装配:

@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

  1. 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

  1. 内嵌Tomcat原理?

答案:

SpringApplication.run

创建WebServerApplicationContext

ServletWebServerFactory

TomcatServletWebServerFactory

new Tomcat()

启动Tomcat

关键点:

  1. Spring Boot直接嵌入Tomcat依赖
  2. 不是war包部署,而是Java main方法启动
  3. Tomcat变成一个类库运行

  1. SpringApplication启动流程?

答案:

new SpringApplication

推断Web应用类型

加载ApplicationContextInitializer

加载ApplicationListener

run

发布ApplicationStartingEvent

准备Environment

创建ApplicationContext

刷新ApplicationContext

调用Runners

发布ApplicationReadyEvent


Spring Cloud #

  1. 注册中心选型?

答案:

对比 Eureka Nacos Consul Zookeeper
CAP AP AP/CP CP CP
健康检查 Client Beat TCP/HTTP/MySQL Script KeepAlive
可用性
社区活跃度 停更 活跃
其他 - 配置中心 多数据中心 大数据生态

推荐: Nacos(注册中心+配置中心二合一)


  1. 服务调用方式对比?

答案:

方式 说明
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);

  1. 网关的作用和实现?

答案:

网关作用:

  1. 统一入口
  2. 路由转发
  3. 负载均衡
  4. 限流熔断
  5. 日志监控
  6. 认证授权

实现对比:

网关 特点
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. 配置中心实现原理?

答案:

核心流程:

1. 应用启动,从配置中心拉取配置
2. 建立长连接监听配置变化
3. 配置变更时收到通知
4. 动态刷新@ConfigurationProperties的Bean

Nacos配置中心原理:

- 长连接 + HTTP回调
- MD5对比,只推送变更
- 本地缓存配置,断网可用

实现类:

// 刷新配置
@RefreshScope // 热刷新
@ConfigurationProperties
public class UserConfig {
}

🔗 相关笔记 #


最后更新: 2026-04-29