框架常用注解
🧩 一、Spring 常用注解(IOC / AOP 核心)
💠 1. IOC 相关(控制反转)
| 注解 | 作用 | 场景 |
|---|---|---|
@Component |
标识一个普通组件,交给 Spring 容器管理 | 普通类 |
@Controller |
表示控制层组件 | Web 控制器 |
@Service |
表示服务层组件 | 业务逻辑层 |
@Repository |
表示 DAO 层组件 | 数据访问层 |
@Autowired |
按类型自动注入 | 字段、构造器、setter |
@Qualifier |
与 @Autowired 联合使用,按名称注入 |
解决多个 Bean 同类型冲突 |
@Resource |
JSR-250 标准注入,按名称优先 | 同上 |
@Value |
注入配置文件中的属性值 | 常量、配置字段 |
@Primary |
指定优先注入的 Bean | 同类型 Bean 多个时 |
@Lazy |
延迟加载 Bean | 优化启动性能 |
💠 2. AOP 相关(切面编程)
| 注解 | 作用 | 场景 |
|---|---|---|
@Aspect |
声明一个切面类 | AOP 切面定义 |
@Before |
方法执行前执行通知 | 前置通知 |
@After |
方法执行后执行通知 | 后置通知(无论异常) |
@AfterReturning |
方法成功返回后执行 | 返回通知 |
@AfterThrowing |
方法异常时执行 | 异常通知 |
@Around |
包裹整个方法(可控制执行时机) | 性能监控、事务控制 |
@Pointcut |
定义切入点表达式 | 统一复用表达式 |
💠 3. 配置相关
| 注解 | 作用 | 场景 |
|---|---|---|
@Configuration |
声明配置类(代替 XML) | JavaConfig |
@Bean |
注册一个 Bean 到容器 | 配合 @Configuration |
@Import |
导入额外配置类 | 组合配置 |
@PropertySource |
加载外部 properties 文件 | 读取配置 |
@ComponentScan |
扫描指定包 | 注册组件 |
@Conditional |
条件加载 Bean | 动态配置 |
🌐 二、Spring MVC 常用注解
💠 1. 控制层映射
| 注解 | 作用 | 场景 |
|---|---|---|
@Controller |
定义控制器类 | Web 层 |
@RestController |
等价于 @Controller + @ResponseBody |
REST 接口 |
@RequestMapping |
定义请求路径、方法 | 类或方法级别 |
@GetMapping / @PostMapping / @PutMapping / @DeleteMapping |
简化版请求映射 | REST 风格接口 |
@RequestParam |
获取请求参数 | ?name=xxx |
@PathVariable |
获取路径参数 | /user/{id} |
@RequestBody |
将 JSON 请求体映射为对象 | POST JSON 请求 |
@ResponseBody |
将返回值序列化为 JSON | REST 返回 |
@ModelAttribute |
绑定模型数据或方法参数 | 表单提交 |
@SessionAttributes |
将数据保存到 session | 登录状态存储 |
💠 2. 异常 & 返回处理
| 注解 | 作用 | 场景 |
|---|---|---|
@ControllerAdvice |
全局异常处理类 | 全局控制器拦截 |
@ExceptionHandler |
指定异常处理方法 | 捕获异常 |
@ResponseStatus |
设置响应状态码 | 返回状态控制 |
@InitBinder |
初始化数据绑定器 | 参数转换 |
💾 三、MyBatis 常用注解
| 注解 | 作用 | 场景 |
|---|---|---|
@Mapper |
标识为 MyBatis 映射接口 | DAO 层接口 |
@Select / @Insert / @Update / @Delete |
编写 SQL 语句 | 简单查询或更新 |
@Results / @Result |
字段映射 | 数据库字段与实体字段名不同 |
@Param |
指定 SQL 参数名 | 多参数方法 |
@Options |
设置主键回填、事务行为等 | 插入时主键自动生成 |
@MapKey |
指定返回 Map 的 key | 查询结果 Map 化 |
🚀 四、Spring Boot 常用注解
| 注解 | 作用 | 场景 |
|---|---|---|
@SpringBootApplication |
核心入口(含 @Configuration, @EnableAutoConfiguration, @ComponentScan) |
启动类 |
@EnableAutoConfiguration |
启用自动配置 | 底层自动装配 |
@ConfigurationProperties |
将配置文件映射为对象 | 封装配置类 |
@EnableConfigurationProperties |
开启上面映射功能 | 配置类启用 |
@ConditionalOnProperty |
当某配置满足时加载 Bean | 条件化配置 |
@ConditionalOnMissingBean |
Bean 不存在时加载 | 自动配置 |
@SpringBootTest |
启动完整 Spring Boot 测试环境 | 单元测试 |
@TestConfiguration |
测试专用配置 | 隔离测试 Bean |
@RestControllerAdvice |
全局异常 + REST 接口 | 统一异常返回 JSON |
🔐 五、Spring Security 常用注解
| 注解 | 作用 | 场景 |
|---|---|---|
@EnableWebSecurity |
开启 Web 安全配置 | Security 配置类 |
@Configuration |
标识配置类 | |
@PreAuthorize |
方法执行前验证权限 | 细粒度控制(SpEL 表达式) |
@PostAuthorize |
方法执行后再验证权限 | 返回后检查 |
@Secured |
指定角色访问权限 | 简单权限控制 |
@RolesAllowed |
与 @Secured 类似(JSR-250) |
指定角色 |
@WithMockUser |
测试时模拟登录用户 | 单元测试 |
@AuthenticationPrincipal |
获取当前登录用户 | Controller 层 |
☁️ 六、Spring Cloud 常用注解(微服务体系)
💠 1. 服务注册与发现(Eureka / Nacos)
| 注解 | 作用 |
|---|---|
@EnableEurekaClient / @EnableDiscoveryClient |
启用服务注册与发现 |
@LoadBalanced |
启用 Ribbon 负载均衡 |
@Value / @RefreshScope |
动态刷新配置(与 Config 一起) |
💠 2. 服务调用(OpenFeign)
| 注解 | 作用 |
|---|---|
@EnableFeignClients |
开启 Feign 客户端 |
@FeignClient(name="service-name") |
定义服务调用接口 |
@RequestMapping / @GetMapping |
映射远程接口路径 |
💠 3. 服务网关(Gateway)
| 注解 | 作用 |
|---|---|
@EnableGateway (部分版本自带) |
启用网关服务 |
@RequestRateLimiter |
限流控制 |
@EnableDiscoveryClient |
注册到注册中心 |
💠 4. 熔断 & 限流(Hystrix / Sentinel)
| 注解 | 作用 |
|---|---|
@EnableHystrix / @EnableCircuitBreaker |
开启熔断机制 |
@HystrixCommand(fallbackMethod="...") |
定义降级逻辑 |
@SentinelResource(value="resourceName", blockHandler="blockHandler") |
Sentinel 控制限流熔断 |
📘 七、面试记忆小技巧
| 模块 | 关键注解记忆点 |
|---|---|
| Spring 核心 | @Component 系列 + @Autowired + @Configuration |
| Spring MVC | @RestController + @RequestMapping + @RequestBody |
| MyBatis | @Mapper + @Select + @Param |
| Spring Boot | @SpringBootApplication + @ConfigurationProperties |
| Security | @EnableWebSecurity + @PreAuthorize |
| Spring Cloud | @EnableDiscoveryClient + @FeignClient + @HystrixCommand |
🌱 一、Spring 核心注解运行机制(IOC / AOP)
1️⃣ @Component 系列注解(Bean 扫描注册流程)
流程图:
1 | Spring 启动 |
关键类:
ClassPathBeanDefinitionScannerScannedGenericBeanDefinitionDefaultListableBeanFactory
时机:
BeanDefinition 阶段(容器刷新 refresh() 时)
2️⃣ @Autowired 注入流程
流程图:
1 | 实例化 Bean |
关键类:
AutowiredAnnotationBeanPostProcessorDefaultListableBeanFactory.resolveDependency()
时机:
Bean 初始化阶段(构造完成后,init 前)
3️⃣ @Configuration + @Bean
流程图:
1 | 启动阶段 |
关键类:
ConfigurationClassPostProcessorEnhancer(CGLIB)BeanDefinitionRegistry
时机:
注册 BeanDefinition 阶段(启动时)
4️⃣ AOP 注解(@Aspect, @Around 等)
流程图:
1 | 启动时 |
关键类:
AnnotationAwareAspectJAutoProxyCreatorAspectJExpressionPointcutProxyFactory
时机:
Bean 初始化结束后创建代理对象阶段
🌐 二、Spring MVC 注解运行机制
1️⃣ @RequestMapping、@GetMapping
流程图:
1 | SpringMVC 启动 |
关键类:
RequestMappingHandlerMappingHandlerMethodDispatcherServlet
时机:
初始化阶段注册映射;请求阶段匹配调用。
2️⃣ @RequestBody / @ResponseBody
流程图:
1 | 请求进入 DispatcherServlet |
关键类:
RequestResponseBodyMethodProcessorMappingJackson2HttpMessageConverter
时机:
请求处理阶段(方法调用前后)
💾 三、MyBatis 注解运行机制
流程图:
1 | Spring 启动时 |
关键类:
MapperScannerConfigurerMapperProxySqlSessionTemplate
时机:
Mapper 代理对象创建阶段 + 调用时动态执行 SQL
🚀 四、Spring Boot 注解运行机制
1️⃣ @SpringBootApplication 自动装配流程
流程图:
1 | 启动类 @SpringBootApplication |
关键类:
SpringApplicationAutoConfigurationImportSelectorSpringFactoriesLoader
时机:
启动阶段(容器刷新前)
🔐 五、Spring Security 注解运行机制
流程图:
1 | @EnableWebSecurity |
关键类:
MethodSecurityInterceptorSecurityFilterChainAccessDecisionManager
时机:
请求进入 Security Filter 阶段 & 方法调用前
☁️ 六、Spring Cloud 注解运行机制
1️⃣ @EnableDiscoveryClient
流程图:
1 | 启动阶段 |
2️⃣ @FeignClient
流程图:
1 | @EnableFeignClients 启动 |
关键类:
FeignClientsRegistrarFeignClientFactoryBeanFeignInvocationHandler
🚨 七、所有框架调用时机总览表
| 阶段 | 注解类型 | 核心执行器 | 时机 |
|---|---|---|---|
| Bean 扫描注册 | @Component 系列 |
ClassPathBeanDefinitionScanner |
容器启动 |
| 依赖注入 | @Autowired |
AutowiredAnnotationBeanPostProcessor |
Bean 初始化阶段 |
| 配置解析 | @Configuration、@Bean |
ConfigurationClassPostProcessor |
容器刷新前 |
| AOP 创建代理 | @Aspect |
AnnotationAwareAspectJAutoProxyCreator |
Bean 初始化后 |
| MVC 映射注册 | @Controller、@RequestMapping |
RequestMappingHandlerMapping |
Web 容器启动 |
| JSON 转换 | @RequestBody、@ResponseBody |
HttpMessageConverter |
请求调用时 |
| MyBatis 代理 | @Mapper |
MapperProxy |
运行时调用接口方法 |
| 自动装配 | @EnableAutoConfiguration |
AutoConfigurationImportSelector |
启动阶段 |
| 权限控制 | @PreAuthorize |
MethodSecurityInterceptor |
方法调用前 |
| 服务注册 | @EnableDiscoveryClient |
DiscoveryClientAutoConfiguration |
启动阶段 |
| 远程调用 | @FeignClient |
FeignClientFactoryBean |
调用接口时 |
🧠 八、面试延伸逻辑(高频问法)
| 典型问题 | 核心回答逻辑 |
|---|---|
@Autowired 注入是怎么实现的? |
通过 AutowiredAnnotationBeanPostProcessor 在 Bean 初始化阶段用反射注入依赖。 |
@Configuration 为什么会生成代理类? |
确保 @Bean 方法多次调用返回同一单例 Bean。 |
| Spring Boot 自动装配的原理? | @EnableAutoConfiguration → AutoConfigurationImportSelector → 读取 spring.factories。 |
| Spring AOP 如何织入? | 使用代理模式(JDK/CGLIB),由 AnnotationAwareAspectJAutoProxyCreator 创建代理对象。 |
| Spring MVC 是如何找到 Controller 的? | RequestMappingHandlerMapping 扫描 @Controller 并建立 URL 映射表。 |
| Feign 是怎么实现远程调用的? | 通过动态代理生成接口实现类,调用时封装 HTTP 请求发往目标服务。 |
太好了 👏
那我们就进入第二阶段:六大框架的深入机制讲解版,把每个框架的注解从“会用”提升到“懂原理、能讲源码逻辑”。
我会按顺序讲,每个模块包含:
1️⃣ 常用注解
2️⃣ 运行机制(源码/原理)
3️⃣ 实战/场景
4️⃣ 面试追问点(能拿高分的深答法)
🌱 一、Spring 核心注解 深入解析(IOC + AOP)
Spring 是一切的根。只要理解它的 IOC 容器和 AOP 原理,后面所有框架的注解你都会秒懂。
1️⃣ IOC 核心注解机制
核心注解:
@Component, @Service, @Repository, @Controller, @Configuration, @Bean, @Scope
🔍 1. 原理
🧩 IOC(Inversion of Control)——控制反转
- 核心思想:对象不由自己创建,而是交给容器管理。
- Spring 容器本质是一个 BeanFactory / ApplicationContext。
- 它启动时会执行:
- 扫描包(
@ComponentScan) - 找到带
@Component系的类 - 实例化成 Bean,放入 IOC 容器
- 执行依赖注入(DI)
- 扫描包(
🧠 底层关键类:
ClassPathScanningCandidateComponentProvider:扫描所有类AnnotationConfigApplicationContext:基于注解的容器入口DefaultListableBeanFactory:Bean 存储与生命周期管理
⚙️ 2. @Component 与派生注解
Spring 在扫描时会判断:
1 | if (clazz.isAnnotationPresent(Component.class) |
👉 所以 @Controller, @Service, @Repository 都是 @Component 的语义扩展,只是方便分层。
⚙️ 3. @Configuration + @Bean 原理
@Configuration标识配置类,本质上是一个带 CGLIB 代理的 Bean。- 代理的目的是防止多次实例化同一个 Bean。
示例:
1 |
|
底层 Spring 会:
- 解析
@Configuration - 生成 CGLIB 代理子类
- 拦截对
@Bean方法的调用 - 若 Bean 已存在,不重新创建
⚙️ 4. 依赖注入注解机制
| 注解 | 机制 |
|---|---|
| @Autowired | 反射注入。先按类型匹配,再按名称。 |
| @Qualifier | 指定注入 Bean 名称。 |
| @Resource | JSR-250 标准,先按名称,再按类型。 |
| @Value | 从 Environment 中取值(支持 ${})。 |
底层类:
AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorValueAnnotationBeanPostProcessor
这些都是在 Bean 初始化阶段执行的 BeanPostProcessor。
2️⃣ AOP 核心注解机制
核心注解:@Aspect, @Before, @After, @Around, @Pointcut
🧩 1. 原理:动态代理 + 通知织入
Spring 启动时:
- 扫描
@Aspect类; - 解析通知方法(
@Before,@Around…); - 生成代理对象(JDK Proxy 或 CGLIB);
- 方法执行时由代理拦截,执行通知逻辑。
例如:
1 |
|
当调用 service 方法时:
1 | JDK 动态代理 → 进入 AOP 代理类 → 执行 before() → 调用原方法 → after() |
底层关键类:
AspectJExpressionPointcutJdkDynamicAopProxyCglibAopProxy
🧠 面试深问点(可直接说出原理)
| 问题 | 答案要点 |
|---|---|
| @Component 和 @Bean 区别? | @Component 自动扫描,@Bean 手动注册;前者类级别,后者方法级别。 |
| @Configuration 为什么要代理? | 为了保证 @Bean 返回的单例不会重复创建。 |
| AOP 是如何实现的? | 基于 JDK/CGLIB 动态代理,通过 ProxyFactory 创建代理对象,执行通知链。 |
| @Autowired 什么时候注入? | 在 BeanPostProcessor 阶段的 postProcessPropertyValues() 里注入。 |
🌐 二、SpringMVC 常用注解深度解析(请求分发 + 参数绑定 + 消息转换)
SpringMVC 是 Spring 的 Web 层框架,它的注解体系围绕 请求映射、参数绑定、返回响应 三大核心展开。
1️⃣ SpringMVC 的整体架构与执行流程
🌊 面试常问:“SpringMVC 请求是怎么从 URL 到 Controller 方法执行的?”
🧩 核心机制:
1 | DispatcherServlet(前端控制器) |
关键点:SpringMVC 初始化时,会扫描所有带有 @Controller、@RestController、@RequestMapping 的类和方法,并建立映射表(HandlerMapping)。
2️⃣ 控制层核心注解(Controller 体系)
| 注解 | 作用 | 说明 |
|---|---|---|
| @Controller | 声明控制层组件 | 返回视图(如 JSP、Thymeleaf) |
| @RestController | = @Controller + @ResponseBody | 返回 JSON 数据 |
| @RequestMapping | 定义请求路径、方法、参数规则 | 可标注在类或方法上 |
| @GetMapping / @PostMapping / @PutMapping / @DeleteMapping | @RequestMapping 的快捷形式 | 仅限制 HTTP Method |
| @ResponseBody | 将返回对象序列化为 JSON | 由 HttpMessageConverter 实现 |
| @RequestBody | 将请求体 JSON 反序列化为对象 | 由 HttpMessageConverter 实现 |
💡 实战示例
1 |
|
🔹 /user/{id} → getUser()
🔹 请求体 JSON → 通过 @RequestBody 自动映射到 User 对象
3️⃣ 请求映射机制(HandlerMapping)
Spring 启动时会注册多个 HandlerMapping 实现类,其中最关键的是:
RequestMappingHandlerMapping
它负责扫描所有 Controller 类的方法并建立 URL 映射:
1 |
|
底层逻辑(源码简化版):
1 | for (Method method : controllerClass.getMethods()) { |
🧠 所以:
- 类上的
@RequestMapping("/user") - 方法上的
@GetMapping("/{id}")
会拼接成完整路径 /user/{id} 注册到映射表中。
4️⃣ 参数绑定注解(HandlerMethodArgumentResolver)
SpringMVC 的参数解析是由 HandlerMethodArgumentResolver 实现的。
它通过一系列解析器解析注解参数。
| 注解 | 对应解析器 | 作用 |
|---|---|---|
| @RequestParam | RequestParamMethodArgumentResolver |
解析 URL 查询参数 |
| @PathVariable | PathVariableMethodArgumentResolver |
解析路径参数 |
| @RequestBody | RequestResponseBodyMethodProcessor |
JSON → 对象 |
| @RequestHeader | RequestHeaderMethodArgumentResolver |
获取请求头 |
| @CookieValue | CookieValueMethodArgumentResolver |
获取 Cookie 值 |
| @ModelAttribute | ModelAttributeMethodProcessor |
表单对象绑定 |
| @SessionAttributes | SessionAttributesHandler |
保留 Session 数据 |
💡 参数绑定示例
1 |
|
🧠 底层逻辑:
- SpringMVC 调用每个
HandlerMethodArgumentResolver; - 找到能处理对应注解的解析器;
- 把请求内容转换成参数。
5️⃣ 响应返回注解(HttpMessageConverter)
SpringMVC 的返回值也通过一系列 HandlerMethodReturnValueHandler 处理。
| 注解 | 对应机制 |
|---|---|
| @ResponseBody | 调用 HttpMessageConverter 序列化返回对象为 JSON |
| @RestController | 相当于全类级别 @ResponseBody |
| @ResponseStatus(HttpStatus.XXX) | 设置 HTTP 状态码 |
| @ControllerAdvice + @ExceptionHandler | 全局异常捕获和统一响应 |
💡 JSON 转换过程原理
当方法标注了 @ResponseBody:
- SpringMVC 使用
RequestResponseBodyMethodProcessor处理; - 调用合适的
HttpMessageConverter; - 常见实现:
MappingJackson2HttpMessageConverter→ 使用 Jackson 转 JSON;StringHttpMessageConverter→ 返回字符串。
反过来:
@RequestBody也是通过同样的HttpMessageConverter将 JSON 转成 Java 对象。
6️⃣ 异常处理与全局控制
| 注解 | 作用 |
|---|---|
| @ExceptionHandler(Exception.class) | 捕获特定异常 |
| @ControllerAdvice | 全局异常/数据绑定处理 |
| @InitBinder | 数据绑定格式化(如时间) |
示例:
1 |
|
🧠 面试追问点与高分答法
| 问题 | 深度答法 |
|---|---|
| SpringMVC 如何将 JSON 转换为对象? | 通过 @RequestBody → RequestResponseBodyMethodProcessor → HttpMessageConverter(默认 Jackson)。 |
| @Controller 与 @RestController 区别? | @RestController = @Controller + @ResponseBody,用于 RESTful API 返回 JSON。 |
| 参数绑定是怎么实现的? | 每个注解对应一个 HandlerMethodArgumentResolver,逐个匹配执行。 |
| DispatcherServlet 做了什么? | 它是前端控制器,负责请求分发、参数解析、调用 Controller、返回视图或 JSON。 |
| @ControllerAdvice 有什么用? | 统一异常处理、数据绑定、全局配置。 |
💾 三、MyBatis 常用注解 + 底层映射原理(Mapper 动态代理机制)
MyBatis 是 Spring 体系中连接数据库的核心 ORM 框架。
与 JPA 不同,它更轻量、可控,常通过 接口 + 注解 / XML 映射 实现 SQL 操作。
一、MyBatis 常用注解总览
| 注解 | 作用 | 使用位置 | 说明 |
|---|---|---|---|
| @Mapper | 标记 Mapper 接口 | 接口 | 告诉 Spring 这是一个 MyBatis Mapper |
| @MapperScan | 批量扫描 Mapper 包 | 启动类或配置类 | 替代逐个写 @Mapper |
| @Select / @Insert / @Update / @Delete | 声明 SQL 语句 | 方法 | 注解式 SQL |
| @Results / @Result | 字段与属性映射 | 方法 | 解决数据库字段与实体属性不一致 |
| @Param | 映射方法参数名 | 方法参数 | SQL 中使用 #{参数名} |
| @Options | 设置 SQL 执行选项 | 方法 | 例如自动主键回填 |
| @SelectProvider / @UpdateProvider … | 动态 SQL 生成 | 方法 | 指定 SQL 由某类动态生成 |
二、Mapper 注册机制与动态代理原理
🧠 面试常问:“@Mapper 是如何让接口不写实现类还能执行 SQL 的?”
核心答案:
👉 MyBatis 使用 动态代理(MapperProxy) 为接口创建实现类。
💡 执行流程示意
1 | 接口调用 → MapperProxy.invoke() → SqlSession → 执行 SQL → 映射结果 → 返回对象 |
详细步骤:
1️⃣ Spring 启动时,@MapperScan 扫描包路径:
1 |
2️⃣ Spring 会为每个接口创建 MapperFactoryBean,交给 IOC 容器管理。
3️⃣ 当注入 Mapper 时,例如:
1 |
|
其实注入的是一个由 MyBatis 创建的代理对象。
4️⃣ 代理对象的核心类:
1 | public class MapperProxy<T> implements InvocationHandler { |
5️⃣ 最终执行 SQL:
- 从注解或 XML 读取 SQL;
- 替换参数;
- 执行 JDBC;
- 使用
ResultSetHandler将结果映射成对象。
三、注解式 SQL 示例
1️⃣ 基本 CRUD 注解
1 |
|
🧩 说明:
#{}会被 MyBatis 解析为?占位符;@Options(useGeneratedKeys=true)可自动回填主键;@Param显式指定参数名,防止参数混乱。
2️⃣ 结果映射注解(解决字段名不匹配)
数据库字段 → Java 属性不一致时:
1 |
|
底层使用 ResultSetHandler 将列值与属性对应。
3️⃣ 动态 SQL 注解
用于复杂 SQL(可条件拼接):
1 |
|
SQL 动态生成类:
1 | public class UserSqlProvider { |
四、@Mapper 与 @MapperScan 的关系
| 场景 | 用法 |
|---|---|
| 少量 Mapper | 每个接口加 @Mapper |
| 多个 Mapper | 在配置类加 @MapperScan(“com.example.mapper”) |
📦 Spring Boot 中通常只需:
1 |
|
五、底层关键组件解析(源码角度)
| 组件 | 作用 |
|---|---|
| SqlSessionFactoryBean | 生成 SqlSession 工厂 |
| MapperFactoryBean | 每个 Mapper 的代理工厂 |
| MapperProxy | 动态代理核心 |
| Executor | 执行 SQL 的底层执行器 |
| ResultSetHandler | 结果集映射 |
| StatementHandler | 负责预编译和执行 SQL |
🧩 执行链:
1 | MapperProxy.invoke() |
六、MyBatis + Spring 的整合机制
Spring Boot 整合时,核心是:
MyBatisAutoConfiguration- 自动注册
SqlSessionFactory和MapperScannerConfigurer - 自动扫描带 @Mapper 的接口
配置简化到只需:
1 | spring.datasource.url=... |
七、面试追问点(高分回答)
| 问题 | 深度答法 |
|---|---|
| @Mapper 与 @MapperScan 区别? | @Mapper 作用于接口;@MapperScan 作用于包;底层都注册 MapperFactoryBean。 |
| MyBatis 是如何执行 SQL 的? | MapperProxy 拦截方法 → SqlSession → Executor → StatementHandler → JDBC 执行。 |
| 注解与 XML 映射的区别? | 注解轻量、便于维护小 SQL;XML 更灵活,支持动态标签、条件判断。 |
| MyBatis 如何实现参数和结果映射? | 参数:通过 ParameterHandler 替换占位符;结果:ResultSetHandler 根据 ResultMap 映射。 |
| @SelectProvider 有什么用? | 用于动态生成 SQL,支持复杂查询逻辑。 |
🌸 四、Spring Boot 常用注解与底层机制(自动装配 + 条件加载)
这一部分是面试高频 + 实战必懂的核心。
重点是理解 Spring Boot 为什么能“自动装配”,以及这些注解在底层是怎么工作的。
一、Spring Boot 核心注解全图
| 注解 | 作用 | 核心原理 |
|---|---|---|
@SpringBootApplication |
核心入口注解(整合 3 个注解) | 启动自动配置与组件扫描 |
@SpringBootConfiguration |
标识配置类 | 继承自 @Configuration |
@EnableAutoConfiguration |
自动装配核心 | 从 META-INF/spring.factories 加载配置类 |
@ComponentScan |
包扫描 | 扫描项目包路径下的组件 |
@ConfigurationProperties |
绑定配置文件属性 | 从 application.yml 绑定属性到 Bean |
@Conditional 系列 |
条件装配 | 控制 Bean 是否加载 |
@Import |
导入配置类 | 支持多种导入方式(类、Selector、Registrar) |
@Value |
注入单个配置值 | 读取 Environment 中的配置 |
@RestController |
= @Controller + @ResponseBody |
快速创建 REST API |
@SpringBootTest |
测试启动 | 启动完整 SpringBoot 环境进行单元测试 |
二、核心注解剖析
⚙️ 1️⃣ @SpringBootApplication(入口注解)
这是 Spring Boot 应用的入口:
1 |
|
组成结构
1 |
|
👉 所以它本质上是:
- 声明一个配置类
- 启动自动装配
- 开启组件扫描
⚙️ 2️⃣ @EnableAutoConfiguration(自动装配核心)
这是 Spring Boot 最重要的注解!
底层逻辑:
- 通过
SpringFactoriesLoader读取所有META-INF/spring.factories文件; - 找到 key 为
org.springframework.boot.autoconfigure.EnableAutoConfiguration的类; - 把这些类加载进容器;
- 根据
@Conditional系列判断是否生效。
这些类通常是:
1 | DataSourceAutoConfiguration |
这些就是所谓的“自动装配类”。
🔍 自动装配核心源码逻辑
在 AutoConfigurationImportSelector 类中:
1 | List<String> configurations = SpringFactoriesLoader.loadFactoryNames( |
每个自动配置类都像这样:
1 |
|
所以:
✅ 有 DataSource 类存在时才加载
✅ 会自动从 application.yml 绑定属性
⚙️ 3️⃣ 条件装配注解(Conditional 系列)
| 注解 | 含义 |
|---|---|
@ConditionalOnClass |
类存在时加载 |
@ConditionalOnMissingBean |
Bean 不存在时加载 |
@ConditionalOnProperty |
指定配置项满足条件时加载 |
@ConditionalOnMissingClass |
类不存在时加载 |
@ConditionalOnWebApplication |
当前为 Web 环境时加载 |
@ConditionalOnExpression |
满足 SpEL 表达式时加载 |
例如:
1 |
|
👉 只有当配置文件里有 app.feature.enabled=true 时才加载。
⚙️ 4️⃣ @ConfigurationProperties(配置绑定)
自动绑定配置文件中的属性:
1 | server: |
底层机制:
- 通过
Binder绑定 Environment 中的属性; - 利用
RelaxedDataBinder支持松散匹配; - 可以用
@EnableConfigurationProperties显式启用。
⚙️ 5️⃣ @Import(手动扩展装配)
四种导入方式:
| 类型 | 示例 | 说明 |
|---|---|---|
| 导入类 | @Import(MyConfig.class) |
导入配置类 |
| 导入 ImportSelector | @Import(MyImportSelector.class) |
批量导入配置类 |
| 导入 ImportBeanDefinitionRegistrar | @Import(MyRegistrar.class) |
动态注册 Bean |
| 导入普通 Bean | @Import({A.class, B.class}) |
多类导入 |
面试常问:
“Spring Boot 自动装配用的是哪种方式?”
答:ImportSelector(AutoConfigurationImportSelector)
三、Spring Boot 启动流程(重点)
当你执行 SpringApplication.run() 时,实际发生了:
1️⃣ 创建 SpringApplication 实例
2️⃣ 推断应用类型(Web/Reactive/None)
3️⃣ 加载 ApplicationContext
4️⃣ 扫描主类所在包
5️⃣ 加载自动配置类(EnableAutoConfiguration)
6️⃣ 实例化 Bean + 依赖注入
7️⃣ 启动内嵌服务器(Tomcat/Jetty/Undertow)
四、面试深问点(高分答法)
| 问题 | 高分答法 |
|---|---|
| Spring Boot 为什么能自动装配? | 因为 @EnableAutoConfiguration 通过 SpringFactoriesLoader 从 META-INF/spring.factories 加载自动配置类,并结合 @Conditional 系列按条件注册 Bean。 |
| @SpringBootApplication 里面包含了什么? | 它整合了 @Configuration、@EnableAutoConfiguration、@ComponentScan。 |
| @ConfigurationProperties 和 @Value 区别? | 前者用于批量属性绑定(对象映射),后者用于单值注入。 |
| Spring Boot 启动流程? | run → 创建 ApplicationContext → 扫描组件 → 自动装配 → 启动容器(Tomcat)。 |
| 自动装配失效的原因有哪些? | 类缺失、条件不满足(@Conditional)、配置关闭(spring.autoconfigure.exclude)。 |
🛡️ 五、Spring Security 常用注解与底层机制(认证与授权)
Spring Security 是企业级安全框架,核心在于 认证(Authentication) 和 授权(Authorization)。
注解只是暴露给开发者的快捷入口,底层依靠 过滤器链 + 访问决策管理器 实现安全控制。
一、核心注解总览
| 注解 | 作用 | 使用场景 |
|---|---|---|
| @EnableWebSecurity | 启用 Spring Security | 配置类上 |
| @Configuration | 配置类 | 配合@EnableWebSecurity |
| @Secured | 方法级权限 | 限制角色访问,老版本 |
| @PreAuthorize | 方法前表达式授权 | 支持 SpEL 表达式,推荐 |
| @PostAuthorize | 方法后表达式授权 | 可基于返回值做授权判断 |
| @RolesAllowed | JSR-250 标准 | 限制角色访问 |
| @WithMockUser | 测试模拟用户 | 单元测试 |
| @AuthenticationPrincipal | 获取当前认证用户 | Controller 方法参数注入 |
二、核心机制解析
1️⃣ FilterChainProxy(安全过滤器链)
Spring Security 基于 Servlet Filter 实现,核心流程:
1 | 请求 → FilterChainProxy → SecurityFilters(多个) → DispatcherServlet |
- 常用 Filter:
UsernamePasswordAuthenticationFilter:表单登录BasicAuthenticationFilter:HTTP BasicExceptionTranslationFilter:异常处理FilterSecurityInterceptor:最终授权决策
💡 面试高频:
“Spring Security 如何拦截请求?”
答:通过FilterChainProxy,按顺序执行过滤器链,每个 Filter 负责不同安全功能。
2️⃣ @EnableWebSecurity
- 激活 Web 安全配置;
- 内部通过
@Import(WebSecurityConfiguration.class)注入:FilterChainProxyAuthenticationManagerAccessDecisionManager
3️⃣ 方法级权限注解
a. @Secured
1 |
|
- 仅支持角色(ROLE_ 前缀)
- 核心类:
SecuredAnnotationSecurityMetadataSource
b. @PreAuthorize / @PostAuthorize
1 |
|
- 支持 SpEL 表达式,可基于方法参数、返回值、认证对象授权
- 核心类:
ExpressionBasedAnnotationAttributeFactoryPreInvocationAuthorizationAdviceVoter
c. @RolesAllowed
- JSR-250 标准,底层映射到
Jsr250MethodSecurityMetadataSource
4️⃣ 获取当前用户注解
@AuthenticationPrincipal
1 |
|
- 注入当前认证对象
- 底层通过
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
5️⃣ 测试支持
@WithMockUser
1 |
|
- 模拟登录用户,方便方法级安全测试
6️⃣ 身份认证流程(核心链条)
- 用户请求登录
/login UsernamePasswordAuthenticationFilter拦截请求- 调用
AuthenticationManager→ProviderManager - 执行
UserDetailsService.loadUserByUsername获取用户信息 - 验证密码 → 生成
Authentication→ 存入SecurityContextHolder - 后续请求通过过滤器链进行授权检查
7️⃣ 授权决策
- 核心类:
AccessDecisionManager - 核心逻辑:
- 获取请求 URL / 方法的权限元信息(MetadataSource)
- 通过
Voter投票机制判定允许或拒绝 - 常用 Voter:
RoleVoterAuthenticatedVoterExpressionVoter(用于 @PreAuthorize / @PostAuthorize)
三、面试追问点(高分回答)
| 问题 | 高分答法 |
|---|---|
| Spring Security 如何拦截请求? | 通过 FilterChainProxy 执行多个 Filter,每个 Filter 完成认证或授权逻辑。 |
| @PreAuthorize 与 @Secured 区别? | @Secured 仅支持角色,@PreAuthorize 支持 SpEL 表达式,可基于方法参数/返回值授权。 |
| 当前用户怎么获取? | SecurityContextHolder.getContext().getAuthentication().getPrincipal() 或 @AuthenticationPrincipal 注入。 |
| FilterChain 执行顺序? | 登录认证 → 异常处理 → 授权 → 业务 Controller → 响应处理。 |
| 如何测试方法级安全? | 使用 @WithMockUser 注解模拟用户身份。 |
☁️ 六、Spring Cloud 常用注解与底层机制(服务注册、发现、负载均衡、远程调用)
Spring Cloud 是微服务架构核心框架,它提供了 服务治理、配置中心、服务调用、熔断降级 等功能。
我们重点分析 常用注解 + 底层原理 + 面试追问点。
一、服务注册与发现(Eureka / Nacos)
1️⃣ 核心注解
| 注解 | 作用 |
|---|---|
@EnableEurekaClient |
启用 Eureka 客户端,自动注册服务 |
@EnableDiscoveryClient |
通用服务发现注解(Eureka、Consul、Nacos) |
@LoadBalanced |
配置 RestTemplate 或 WebClient 支持客户端负载均衡 |
@RefreshScope |
配置热刷新,用于配置中心动态刷新 |
2️⃣ 服务注册流程(Eureka 示例)
- 启动微服务 →
EurekaClient初始化 - 发送心跳
POST /eureka/apps/{serviceName} - Eureka Server 接收并注册实例
- 其他微服务通过
/eureka/apps获取服务列表 - 内部缓存一份服务列表,提高访问效率
🔥 面试点:Eureka 默认 心跳 30s,下线延迟 90s,可能存在短暂不可用。
二、负载均衡(Ribbon / Spring Cloud LoadBalancer)
1️⃣ 核心注解
| 注解 | 作用 |
|---|---|
@LoadBalanced |
配置 RestTemplate 或 WebClient 支持 Ribbon 或 Spring Cloud LoadBalancer |
@FeignClient |
声明式远程调用,集成负载均衡和熔断 |
2️⃣ 客户端负载均衡原理
- Ribbon(老版):
- 从服务发现获取服务列表
- 使用负载策略(轮询、随机、权重)选择实例
- 发起请求
- Spring Cloud LoadBalancer(新方案):
- 默认轮询算法
- 支持自定义策略
- 通过
LoadBalancerClient或ReactiveLoadBalancer选择实例
三、声明式远程调用(Feign)
1️⃣ 核心注解
| 注解 | 作用 |
|---|---|
@EnableFeignClients |
启用 Feign 客户端扫描 |
@FeignClient(name="service-name", path="/api") |
声明远程服务接口 |
@RequestMapping / @GetMapping / @PostMapping |
定义远程调用接口方法 |
2️⃣ Feign 调用原理
1 | FeignClient Proxy(动态代理) |
3️⃣ 示例
1 |
|
调用
userClient.getUser(1L)时:
- Feign 创建动态代理对象
- 使用服务注册中心获取可用实例
- 通过 HTTP 发起请求
- 返回 JSON 转对象
四、网关(Spring Cloud Gateway)
核心注解
| 注解 | 作用 |
|---|---|
@EnableGateway |
启用网关(Spring Boot 自动装配即可) |
@Bean RouteLocator |
配置路由规则 |
@Configuration |
配置类,定义自定义过滤器 |
核心原理
- 基于 WebFlux / Netty 实现异步非阻塞网关
- 请求 → GlobalFilter → RouteLocator 匹配 → 目标服务
- 支持限流、熔断、重试、认证等功能
五、熔断与降级(Resilience4j / Spring Cloud CircuitBreaker)
核心注解
| 注解 | 作用 |
|---|---|
@EnableCircuitBreaker |
启用熔断器 |
@CircuitBreaker(name="backend", fallbackMethod="fallback") |
方法级熔断 |
@Retryable |
方法重试 |
@TimeLimiter |
异步方法超时控制 |
原理
- 调用被监控方法
- 出现异常或超时,熔断器计数器累加
- 达到阈值 → 打开熔断,直接调用 fallback
- 超过时间或条件恢复 → 关闭熔断器
六、面试高频问点
| 问题 | 高分回答 |
|---|---|
| Spring Cloud 如何实现服务注册与发现? | 微服务启动注册到 Eureka/Nacos,通过客户端缓存获取可用服务列表,实现服务调用。 |
| @FeignClient 如何负载均衡? | 结合 Ribbon 或 Spring Cloud LoadBalancer,通过服务注册中心获取实例列表,并按策略选择。 |
| 网关路由原理? | 请求经过 GlobalFilter → RouteLocator 匹配 → Forward 到目标服务,支持限流、认证、熔断。 |
| 熔断器是怎么工作的? | 通过 CircuitBreaker 监控方法调用,达到阈值时打开熔断,调用 fallback 方法。 |
| @RefreshScope 作用? | 允许 Bean 在配置中心更新时热刷新,不重启应用即可生效。 |
完全可以 😎!我帮你整理一份 六大框架超级速记卡 / 可打印版知识图谱,兼顾:
- 结构图:模块 + 核心注解分类
- 流程链:底层执行顺序(请求 → 执行 → 返回)
- 时机表:各注解触发时机 / 生命周期
我设计成一页 A4 可打印的面试速记卡风格,每个框架重点突出高频面试点。
样例结构(六大框架速查卡)
1️⃣ Spring 核心注解 & 生命周期
模块结构图:
1 | @Component / @Service / @Repository / @Controller |
执行链:
1 | Bean 定义加载 → BeanPostProcessor → 初始化(@PostConstruct) → 依赖注入完成 → Bean 可用 |
时机表:
| 注解 | 触发时机 |
|---|---|
| @Component/@Service | 容器启动扫描注册 |
| @Autowired | Bean 初始化阶段注入 |
| @PostConstruct | Bean 初始化后立即调用 |
| @PreDestroy | 容器关闭前调用 |
2️⃣ SpringMVC 注解 & 请求处理
结构图:
1 | @Controller / @RestController |
执行链:
1 | HTTP 请求 → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → ViewResolver → Response |
时机表:
| 注解 | 触发时机 |
|---|---|
| @ControllerAdvice | Controller 异常触发 |
| @InitBinder | Controller 方法调用前绑定参数 |
| @RequestBody / @ResponseBody | 方法调用序列中请求解析 & 响应序列化 |
3️⃣ MyBatis 注解 & SQL 执行
结构图:
1 | @Mapper / @MapperScan |
执行链:
1 | 接口方法调用 → MapperProxy.invoke() → SqlSession.select() → Executor → JDBC → ResultSet → 映射到对象 |
时机表:
| 注解 | 触发时机 |
|---|---|
| @MapperScan | 容器启动时扫描 Mapper |
| @Select / @Insert | 方法调用时解析 SQL |
| @Param | 方法调用解析参数 |
| @Results | 执行 SQL 返回结果映射 |
4️⃣ Spring Boot 注解 & 自动装配
结构图:
1 | @SpringBootApplication |
执行链:
1 | SpringApplication.run() → ApplicationContext 创建 → 自动配置加载 → Bean 实例化 → 自动装配 → 容器启动 |
时机表:
| 注解 | 触发时机 |
|---|---|
| @EnableAutoConfiguration | ApplicationContext 创建阶段 |
| @ConditionalOnClass / OnMissingBean | Bean 实例化前条件判断 |
| @ConfigurationProperties | Bean 实例化绑定属性 |
| @Value | Bean 初始化注入属性 |
5️⃣ Spring Security 注解 & 权限控制
结构图:
1 | @EnableWebSecurity |
执行链:
1 | 请求 → FilterChainProxy → AuthenticationManager → UserDetailsService → 验证 → SecurityContextHolder → 授权 → Controller |
时机表:
| 注解 | 触发时机 |
|---|---|
| @EnableWebSecurity | 容器启动配置安全过滤器链 |
| @PreAuthorize / @Secured | 方法调用前判断权限 |
| @PostAuthorize | 方法执行后基于返回值判断 |
| @AuthenticationPrincipal | Controller 方法参数注入当前用户 |
6️⃣ Spring Cloud 注解 & 微服务调用
结构图:
1 | @EnableEurekaClient / @EnableDiscoveryClient |
执行链:
1 | 客户端请求 → 服务注册中心获取实例 → 负载均衡选择 → 远程调用 → 返回 → 熔断/降级处理 |
时机表:
| 注解 | 触发时机 |
|---|---|
| @EnableEurekaClient | 启动时注册服务 |
| @FeignClient | 接口方法调用时生成动态代理发 HTTP |
| @LoadBalanced | RestTemplate 调用前选择服务实例 |
| @CircuitBreaker | 方法执行异常或超时触发 |
