当前位置: 首页 > news >正文

Spring Boot注解全解:从入门到精通(面试避坑版)

Spring Boot注解全解:从入门到精通(面试避坑版)

本文系统梳理Spring Boot中最常用的注解,按照启动配置、Web层、IoC容器、AOP事务、属性绑定、条件注解六大分类逐一拆解。每个注解都配有作用说明、代码示例、实战避坑,帮助你彻底掌握Spring Boot注解体系。

一、注解为什么如此重要?

在Spring Boot中,注解是“约定大于配置”的核心体现。它们极大地简化了开发,把繁琐的XML配置变成了一行行简洁的元数据。

XML时代 vs 注解时代

xml

<!-- XML时代:繁琐的配置 --> <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao"/> </bean> <bean id="userDao" class="com.example.UserDao"/>

java

// 注解时代:简洁优雅 @Service public class UserService { @Autowired private UserDao userDao; }

核心思想:注解让开发者从“怎么配置”转向“做什么”,是Spring Boot快速开发的基础。

二、启动与配置类注解(门面担当)

2.1 @SpringBootApplication

Spring Boot应用的入口注解,标注在启动类上。

java

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

面试重点@SpringBootApplication组合注解,等价于:

注解作用
@Configuration标识为配置类
@EnableAutoConfiguration开启自动配置
@ComponentScan扫描当前包及子包的Bean

避坑@ComponentScan默认扫描启动类所在包及其子包。如果Bean在其他包中,需要通过@ComponentScan(basePackages = "com.example.other")手动指定。

2.2 @EnableAutoConfiguration

开启Spring Boot的自动配置功能。

原理:通过@Import(AutoConfigurationImportSelector.class)读取META-INF/spring.factoriesMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,加载所有自动配置类。

面试金句:“自动配置的核心是@EnableAutoConfiguration,它通过@Import导入选择器,读取spring.factories文件中的配置类,再配合@Conditional条件注解按需加载。”

2.3 @ComponentScan

扫描指定包下的@Component及其衍生注解(@Service@Controller@Repository等),将它们注册为Spring Bean。

java

@ComponentScan(basePackages = {"com.example.service", "com.example.dao"}) @SpringBootApplication public class Application { // ... }

避坑:扫描不到Bean会抛出NoSuchBeanDefinitionException

三、Web层注解(Controller与参数绑定)

3.1 @RestController

标识一个类为RESTful控制器,所有方法默认返回JSON数据(不进行页面跳转)。

java

@RestController @RequestMapping("/user") public class UserController { @GetMapping("/{id}") public User getUser(@PathVariable Long id) { return userService.getById(id); } }

本质@RestController=@Controller+@ResponseBody

  • @Controller:标识控制器,默认返回视图(页面)

  • @ResponseBody:方法返回值直接写入HTTP响应体(JSON/文本)

3.2 @RequestMapping / @GetMapping / @PostMapping

路由映射注解,将HTTP请求映射到处理方法。

java

@RestController @RequestMapping("/api/user") // 类上一级路径 public class UserController { @GetMapping("/{id}") // GET /api/user/1 public User get(@PathVariable Long id) { ... } @PostMapping // POST /api/user public User add(@RequestBody User user) { ... } @PutMapping("/{id}") // PUT /api/user/1 public User update(@PathVariable Long id, @RequestBody User user) { ... } @DeleteMapping("/{id}") // DELETE /api/user/1 public void delete(@PathVariable Long id) { ... } }
注解等价写法
@GetMapping@RequestMapping(method = RequestMethod.GET)
@PostMapping@RequestMapping(method = RequestMethod.POST)
@PutMapping@RequestMapping(method = RequestMethod.PUT)
@DeleteMapping@RequestMapping(method = RequestMethod.DELETE)

3.3 @RequestParam

接收URL查询字符串(Query String)中的参数。

text

GET /api/user?name=张三&age=25

java

@GetMapping("/user") public String getUser( @RequestParam String name, // 必传 @RequestParam(required = false) Integer age, // 可选 @RequestParam(defaultValue = "1") Integer page // 默认值 ) { return name + "," + age + "," + page; }

避坑:不传required=true的参数会报400错误,可用required=falsedefaultValue解决。

3.4 @PathVariable

接收URL路径中的占位符

text

GET /api/user/123

java

@GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { return userService.getById(id); }

避坑:必须加@PathVariable注解才能将路径{id}映射到方法参数上。如果参数名和占位符名不一致,需指定@PathVariable("id")

3.5 @RequestBody

接收HTTP请求体(Body)中的JSON/XML数据,自动反序列化为Java对象。

java

@PostMapping("/user") public User createUser(@RequestBody User user) { return userService.save(user); }

⚠️ 致命陷阱

  • @RequestBody只能用POST/PUT请求

  • 客户端必须设置Content-Type: application/json

  • 如果传了JSON但不加@RequestBody,Spring会尝试用字段名匹配Query String,导致解析失败

3.6 @RequestHeader

获取HTTP请求头中的值。

java

@GetMapping("/profile") public User getProfile(@RequestHeader("Authorization") String token) { // 常用于获取JWT Token return userService.getByToken(token); }

四、IoC容器注解(Bean的注册与注入)

4.1 Bean注册注解(五大类注解)

注解用途本质
@Component通用组件,注册为Bean最基础的注解
@Service业务逻辑层(Service)@Component的衍生
@Repository数据访问层(DAO)@Component的衍生,额外转化JDBC异常
@Controller控制层(页面跳转)@Component的衍生
@Configuration配置类(定义@Bean方法)@Component的衍生,会被CGLIB代理

java

@Service public class UserService { ... } @Repository public class UserDao { ... } @Configuration public class AppConfig { @Bean public RedisTemplate redisTemplate() { ... } }

面试金句:“@Service@Repository@Controller@Configuration本质上都是@Component,它们是Spring为不同分层提供的语义化注解。”

4.2 依赖注入注解

@Autowired

按类型(ByType)自动装配,Spring容器中匹配的Bean会被注入。

java

// 1. 字段注入(最简洁,但官方不推荐) @Service public class UserService { @Autowired private UserDao userDao; } // 2. 构造器注入(推荐:final修饰,不可变,便于单元测试) @Service public class UserService { private final UserDao userDao; @Autowired public UserService(UserDao userDao) { this.userDao = userDao; } } // 3. Setter注入(灵活性高,但可被修改) @Service public class UserService { private UserDao userDao; @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } }

为什么推荐构造器注入?

优势说明
不可变性字段可以用final修饰,确保注入后不改变
单元测试友好不需要Spring容器,直接用构造器传参即可测试
发现依赖问题早构造时就能发现循环依赖等问题
语义清晰强制明确依赖关系
@Qualifier

按名称(ByName)注入,配合@Autowired解决多个同类型Bean的冲突。

java

public interface MessageService { ... } @Service public class SmsService implements MessageService { ... } @Service public class EmailService implements MessageService { ... } @Service public class NotificationService { @Autowired @Qualifier("smsService") // 指定注入SmsService private MessageService messageService; }
@Primary

当有多个同类型Bean时,标注首选注入的Bean。

java

@Primary @Service public class EmailService implements MessageService { ... }

@Qualifiervs@Primary@Qualifier精准指定,@Primary设置默认(更隐式)。

@Autowired vs @Resource
维度@Autowired@Resource
来源Spring框架Java标准(JSR-250)
注入方式默认ByType默认ByName
匹配失败抛出异常退化为ByType
指定名称@Qualifiername属性

4.3 @Bean

标注在方法上,将方法的返回值注册为Spring容器中的Bean。

java

@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; } }

使用场景

  • 整合第三方库(RedisTemplate、RestTemplate)

  • 需要自定义Bean创建逻辑

  • 无法在类上直接加@Component(如第三方类)

避坑@Bean方法所在的类必须标注@Configuration,否则单例失效@Configuration中的@Bean方法会被CGLIB代理,确保单例)。

五、AOP与事务注解

5.1 @Transactional

声明式事务,用AOP在方法执行前后自动开启、提交、回滚事务。

java

@Service public class OrderService { @Transactional public void createOrder(Order order) { // 1. 插入订单 // 2. 扣减库存 // 3. 扣减余额 // 任意一步失败,全部回滚 } }

⚠️ 事务失效的5种场景(面试必问)

失效场景原因解决方案
方法不是public代理只对public方法生效改为public
同类自调用this.method()绕过代理对象注入自身代理:@Autowired self; self.method()
异常被catch吞掉未抛异常,事务无法判断失败重新抛出或在catch中手动回滚
rollbackFor未指定默认只回滚RuntimeException指定@Transactional(rollbackFor = Exception.class)
数据库引擎不支持事务MyISAM引擎不支持事务使用InnoDB引擎

事务传播行为(7种,重点记2种):

传播行为含义
REQUIRED(默认)当前有事务就加入,没有就新建
REQUIRES_NEW总是新建事务,当前事务挂起

5.2 @Aspect

标识一个类为切面类,用于定义AOP横切逻辑(日志、权限、监控等)。

java

@Aspect @Component public class LogAspect { @Around("execution(* com.example.service.*.*(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms"); return result; } }

六、属性绑定注解

6.1 @Value

application.properties/yml中的单个属性注入到字段中。

yaml

# application.yml server: port: 8080 aliyun: oss: endpoint: https://oss-cn-hangzhou.aliyuncs.com

java

@Component public class AppConfig { @Value("${server.port}") private int port; @Value("${aliyun.oss.endpoint}") private String ossEndpoint; }

注意

  • ${}:取配置文件中的值

  • #{}:Spring Expression Language(SpEL),如@Value("#{systemProperties['java.version']}")

6.2 @ConfigurationProperties

批量绑定配置文件中的一组属性到Java对象。

yaml

# application.yml aliyun: oss: endpoint: https://oss-cn-hangzhou.aliyuncs.com access-key-id: LTAI4G8xxx access-key-secret: xxxxxxx bucket-name: my-bucket

java

@Component @ConfigurationProperties(prefix = "aliyun.oss") @Data public class OssProperties { private String endpoint; private String accessKeyId; private String accessKeySecret; private String bucketName; }

优势:省去一堆@Value,自动映射,类型安全,IDE有自动补全。

6.3 @PropertySource

指定加载自定义配置文件.properties文件)。

java

@Configuration @PropertySource("classpath:my-config.properties") public class MyConfig {
http://www.cnnetsun.cn/news/4347532.html

相关文章:

  • OV7670摄像头驱动实战:从FIFO缓存到DMA搬运的完整链路
  • 嵌入式Linux内存调试实战:Electric Fence在ARM平台上的应用与案例分析
  • 基于OpenTelemetry与Prometheus的生成式AI应用监控实战
  • 基于Spring Boot构建工业生产计划管理系统:从核心流程到技术实现
  • MPU9250与MPL库在STM32F1上的移植实战经验
  • 2004-2023美赛O奖论文拆解:价值、整理与迁移实战
  • iOS虚拟摄像头:基于AVFoundation与VideoToolbox的视频管道
  • COC Replay制作全流程:本地语音转写、多角色配音、AI立绘与ffmpeg合成实战指南
  • Qt电力组态软件开发实战:核心架构、图元编辑与数据驱动
  • 正点原子Mini STM32F103RCT6驱动RC522读卡程序详解
  • 5.2kW猛火燃气灶怎么选?嵌入式台式两用安装与验收指南
  • 大模型部署优化:从MiniMax M3与SambaNova集成看专用硬件推理实践
  • 联想校招C语言岗备考指南:从考点拆解到项目实战
  • 实战阶段项目:天气查询桌面应用
  • STM32+HX711电子秤仿真设计:从原理到Proteus实现
  • 从零搭建HP-Lite内网穿透服务:轻量级NAT穿透工具实战指南
  • 重庆南坪商圈餐饮门面转让:会展、通勤和社区客流如何分开算
  • pysoem实现EtherCAT主站通信:从环境搭建到可运行源码实战
  • Claude Code企业级插件开发实战:Skill、命令与MCP集成
  • Pikachu漏洞靶场系列之暴力破解
  • DETR目标检测模型实战:从原理到Hugging Face部署
  • main_window.py(一):主窗口框架与菜单栏|信息化项目全流程管理系统源码逐行精讲(二十六)
  • 基于SpringBoot的黄山旅游在线票务系统毕业设计项目源码文档
  • 大模型推理优化:量化、KV Cache 与吞吐
  • 2026年7月萍乡市新房价格深度分析报告
  • 基于SpringBoot的汽车4S店管理系统设计与实现(源码+lw+部署文档+讲解等)
  • Simscape制冷循环双工况仿真:R134a与R14a对比建模全攻略
  • springboot技能与工具共享小程序29657-计算机课程设计、毕业设计
  • 服装进销存的“隐形分水岭”:当系统学会在问题爆发前“自我修复”
  • 设备状态机怎么写才不乱:挡门、动作、选路,比框架更先要学会