ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

Spring Boot注解全解:从入门到精通(面试避坑版) Spring Boot注解全解从入门到精通面试避坑版本文系统梳理Spring Boot中最常用的注解按照启动配置、Web层、IoC容器、AOP事务、属性绑定、条件注解六大分类逐一拆解。每个注解都配有作用说明、代码示例、实战避坑帮助你彻底掌握Spring Boot注解体系。一、注解为什么如此重要在Spring Boot中注解是“约定大于配置”的核心体现。它们极大地简化了开发把繁琐的XML配置变成了一行行简洁的元数据。XML时代 vs 注解时代xml!-- XML时代繁琐的配置 -- bean iduserService classcom.example.UserService property nameuserDao refuserDao/ /bean bean iduserDao classcom.example.UserDao/java// 注解时代简洁优雅 Service public class UserService { Autowired private UserDao userDao; }核心思想注解让开发者从“怎么配置”转向“做什么”是Spring Boot快速开发的基础。二、启动与配置类注解门面担当2.1 SpringBootApplicationSpring Boot应用的入口注解标注在启动类上。javaSpringBootApplication 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.factories和META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件加载所有自动配置类。面试金句“自动配置的核心是EnableAutoConfiguration它通过Import导入选择器读取spring.factories文件中的配置类再配合Conditional条件注解按需加载。”2.3 ComponentScan扫描指定包下的Component及其衍生注解Service、Controller、Repository等将它们注册为Spring Bean。javaComponentScan(basePackages {com.example.service, com.example.dao}) SpringBootApplication public class Application { // ... }避坑扫描不到Bean会抛出NoSuchBeanDefinitionException。三、Web层注解Controller与参数绑定3.1 RestController标识一个类为RESTful控制器所有方法默认返回JSON数据不进行页面跳转。javaRestController RequestMapping(/user) public class UserController { GetMapping(/{id}) public User getUser(PathVariable Long id) { return userService.getById(id); } }本质RestControllerControllerResponseBodyController标识控制器默认返回视图页面ResponseBody方法返回值直接写入HTTP响应体JSON/文本3.2 RequestMapping / GetMapping / PostMapping路由映射注解将HTTP请求映射到处理方法。javaRestController 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) { ... } }注解等价写法GetMappingRequestMapping(method RequestMethod.GET)PostMappingRequestMapping(method RequestMethod.POST)PutMappingRequestMapping(method RequestMethod.PUT)DeleteMappingRequestMapping(method RequestMethod.DELETE)3.3 RequestParam接收URL查询字符串Query String中的参数。textGET /api/user?name张三age25javaGetMapping(/user) public String getUser( RequestParam String name, // 必传 RequestParam(required false) Integer age, // 可选 RequestParam(defaultValue 1) Integer page // 默认值 ) { return name , age , page; }避坑不传requiredtrue的参数会报400错误可用requiredfalse或defaultValue解决。3.4 PathVariable接收URL路径中的占位符。textGET /api/user/123javaGetMapping(/user/{id}) public User getUser(PathVariable Long id) { return userService.getById(id); }避坑必须加PathVariable注解才能将路径{id}映射到方法参数上。如果参数名和占位符名不一致需指定PathVariable(id)。3.5 RequestBody接收HTTP请求体Body中的JSON/XML数据自动反序列化为Java对象。javaPostMapping(/user) public User createUser(RequestBody User user) { return userService.save(user); }⚠️ 致命陷阱RequestBody只能用POST/PUT请求客户端必须设置Content-Type: application/json如果传了JSON但不加RequestBodySpring会尝试用字段名匹配Query String导致解析失败3.6 RequestHeader获取HTTP请求头中的值。javaGetMapping(/profile) public User getProfile(RequestHeader(Authorization) String token) { // 常用于获取JWT Token return userService.getByToken(token); }四、IoC容器注解Bean的注册与注入4.1 Bean注册注解五大类注解注解用途本质Component通用组件注册为Bean最基础的注解Service业务逻辑层ServiceComponent的衍生Repository数据访问层DAOComponent的衍生额外转化JDBC异常Controller控制层页面跳转Component的衍生Configuration配置类定义Bean方法Component的衍生会被CGLIB代理javaService 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的冲突。javapublic 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。javaPrimary Service public class EmailService implements MessageService { ... }QualifiervsPrimaryQualifier精准指定Primary设置默认更隐式。Autowired vs Resource维度AutowiredResource来源Spring框架Java标准JSR-250注入方式默认ByType默认ByName匹配失败抛出异常退化为ByType指定名称Qualifiername属性4.3 Bean标注在方法上将方法的返回值注册为Spring容器中的Bean。javaConfiguration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(factory); return template; } }使用场景整合第三方库RedisTemplate、RestTemplate需要自定义Bean创建逻辑无法在类上直接加Component如第三方类避坑Bean方法所在的类必须标注Configuration否则单例失效Configuration中的Bean方法会被CGLIB代理确保单例。五、AOP与事务注解5.1 Transactional声明式事务用AOP在方法执行前后自动开启、提交、回滚事务。javaService 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横切逻辑日志、权限、监控等。javaAspect 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.comjavaComponent public class AppConfig { Value(${server.port}) private int port; Value(${aliyun.oss.endpoint}) private String ossEndpoint; }注意${}取配置文件中的值#{}Spring Expression LanguageSpEL如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-bucketjavaComponent 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文件。javaConfiguration PropertySource(classpath:my-config.properties) public class MyConfig {
返回列表