Spring Boot 注解求生指南
前言:
在初次开发一个以springboot为核心的后端项目时,了解到了许多新知识,尤其是spring框架下的注解,由于知识点过多,我就想着按功能模块对这些知识点进行了一次梳理,总结成一篇学习笔记,希望能帮到同样在踩坑的初学者。ps:这篇笔记是自己整理的,有写得不对或是不恰当之处,还望各位大佬赐教。
第一部分:Lombok —— 程序员的“偷懒”神器
在写实体类的时候,以前总要写一堆get/set、toString,代码又长又丑。引入 Lombok 后,几个注解全搞定。
@Data:全能选手。自动生成 getter、setter、toString、equals 和 hashCode 方法。注意:它相当于把下面几个注解打包了,虽然好用,但在涉及到继承时可能会有坑(因为生成的 equals 会比较父类属性),初学阶段无脑用就行。@AllArgsConstructor:全参构造器。一键生成包含所有成员变量的构造方法。@NoArgsConstructor:无参构造器。- 补充逻辑:为什么要把这两个放在一起说?因为在 Java 中,如果你手动写了一个有参构造,编译器就不再默认提供无参构造了。但在 Spring(比如 MyBatis-Plus 或 JSON 反序列化)底层创建对象时,强烈依赖无参构造。所以这两个经常成对出现在实体类上。
@Slf4j:日志注解。相当于自动帮你写了一句private static final Logger log = LoggerFactory.getLogger(当前类.class);。直接用log.info()打印日志,比System.out.println()高级多了,因为后者在生产环境中根本无法关闭,且没有时间、级别等信息。
第二部分:三层架构与依赖注入(核心中的核心)
Spring 的灵魂就是控制反转(IoC)和面向切面编程(AOP),下面这些注解就是用来告诉 Spring 容器:“请帮我管这个类”。
@RestController:加在 Controller 层。它是@Controller+@ResponseBody的组合。意思是:这是一个处理 HTTP 请求的组件,并且返回的不是网页(视图),而是 JSON 数据(现在前后端分离都是这么干的)。@Service:加在 Service 层的业务逻辑类上。告诉 Spring 这是一个业务 Bean,把它放到 Spring 容器里。@Mapper:加在 Dao 层(MyBatis 的 Mapper 接口)上。你只写接口,不加实现类,MyBatis 看到这个注解,就会在底层用动态代理自动帮你生成实现类,直接连数据库。再补充一个相关知识点:@MapperScan注解,通常在启动类上@MapperScan(“com.example.mapper”),这样就不用在每个 Mapper 接口上写 @Mapper 了。@Autowired:自动装配。当 Controller 需要 Service 时,加上它,Spring 就会自动把对应的 Bean 注入进来。- 深度一点:它按照类型(ByType)注入。初学者可能会遇到一个接口有两个实现类导致报错的情况,这时候可以配合
@Qualifier("实现类名")来指定具体的Bean名称。官方更推荐构造器注入。从 Spring 4.3 开始,如果类只有一个构造方法,可以省略 @Autowired,Spring 会自动完成注入。
- 深度一点:它按照类型(ByType)注入。初学者可能会遇到一个接口有两个实现类导致报错的情况,这时候可以配合
第三部分:HTTP 请求路由与参数获取(前端怎么传,后端怎么接)
这是写接口最频繁用的部分。
1. 路由映射(定义 URL):
@RequestMapping:老大哥,可以放在类上(表示该类下的所有接口的公共前缀),也可以放在方法上。可以通过method属性指定 GET 或 POST。@GetMapping/@PostMapping/@PutMapping/@DeleteMapping:老大哥的简写。对应 RESTful 风格的增删改查(查GET、增POST、改PUT、删DELETE)。代码更整洁。
2. 参数接收(前端数据怎么进方法里):@RequestParam:接 URL 后面的问号传参。比如?name=张三。默认前端必须传,如果允许不传,要设置required = false。@PathVariable:接 URL 路径里的参数。比如/users/{id},方法里写@PathVariable Long id,它就能把 URL 里的 id 提取出来。这是 RESTful 风格的标志。@RequestBody:重点!接收前端传来的 JSON 字符串,并自动把它反序列化成 Java 对象。- ⚠️ 避坑指南:
@RequestBody只能用一次(因为它要把整个请求体读出来),而且通常只配合 POST/PUT 使用。千万别和@RequestParam混用,初学者最容易犯的错误就是前端发了 JSON,后端没用@RequestBody接,导致全变成 null。
- ⚠️ 避坑指南:
第四部分:配置、过滤与事务(进阶一点的“基建”)
@Configuration:配置类注解。相当于以前那个烦人的applicationContext.xml文件。里面通常配合@Bean注解,用来手动把第三方库的类(比如 RedisTemplate)交给 Spring 管理。@Transactional:事务注解。加在 Service 层的方法上。- 深度理解:数据库操作讲究“要么全成功,要么全失败”(比如转账,A扣钱B加钱不能只成功一半)。加上这个注解,如果方法里抛了异常,Spring 会自动回滚数据库操作。默认回滚的是RuntimeException 及其子类 和 Error不会回滚 Exception(受检异常),除非显式配置 rollbackFor = Exception.class
@WebFilter:Servlet 规范的过滤器。常用来做全局处理,比如:统一解决跨域问题、统一校验 JWT 登录 token、记录请求耗时等。请求到达 Controller 之前,会先经过 Filter。@Result:这里做个特别说明。MyBatis 的@Result是用于 XML/注解方式配置结果集映射(如 @Results + @Result)。此处提到的Result类:是项目封装的统一响应体(如 Result),这不是注解,而是一个泛型类。为了接口规范,我们不会直接返回数据,而是包一层:return Result.success(data);里面包含了状态码、提示信息和真实数据。
第五部分:自定义注解(触碰底层魔法)
当你发现上面那些注解不够用时,你就会想自己写注解。写自定义注解离不开“元注解”(也就是加在注解上面的注解)。
@Target(ElementType.METHOD):定义你的注解能用在哪里。ElementType.METHOD表示只能加在方法上。- 补充:还有
TYPE(加在类上)、FIELD(加在属性上)等。
@Retention(RetentionPolicy.RUNTIME):定义你的注解能存活多久。RUNTIME表示运行时依然保留。这极其重要!因为只有保留到运行时,我们才能通过 Java 的反射机制在程序跑起来的时候获取到这个注解的信息,进而执行逻辑。
@annotation:这不是一个加在类上的注解,而是用在AOP 切面表达式里的。- 联动理解:假设你自定义了一个
@MyLog注解(加了上面两个元注解),想实现“只要方法加了@MyLog,就自动打印日志”。在写 AOP 切面类时,切入点就要写成@annotation(包名.MyLog)。它的意思是:“拦截所有标有@MyLog注解的方法”。
- 联动理解:假设你自定义了一个
总结与感悟:
整理完才发现,这些注解并不是孤立的。Lombok 帮我们简化实体类,MVC 注解帮我们分层和打通 HTTP,配置与事务注解保证了项目的健壮性,而元注解则给了我们无限扩展的可能。它们底层的核心其实就是反射和动态代理。这些知识点刚学确实会觉得像背天书,但只要多写几个 CRUD,多调试几次报错,这些@就会变成你肌肉记忆。无限进步!
