资讯详情

40 个 SpringBoot 常用注解:让生产力爆表!

📅 2026/9/26 4:17:07 | 华诺云谱 👁 阅读
40 个 SpringBoot 常用注解:让生产力爆表!
一、写在前面为什么注解如此重要Spring Boot 之所以能够大幅降低 Java 后端开发的复杂度一个非常重要的原因就是把原来需要写大量 XML 配置、手动组装 Bean、编写样板代码的工作全部浓缩成一个个简洁的注解。开发者只需要在类、方法、字段或参数上打上一个注解框架就能在运行时自动完成依赖注入、请求映射、事务代理、参数校验等一系列繁琐操作。本篇内容精心整理了 Spring Boot 开发中最常用的 40 个注解按照「启动与自动装配、组件注册与分层、依赖注入与配置读取、Bean 作用域与生命周期、Web 层请求处理、参数校验、事务与缓存」八大分类逐一详解。每个注解都会从功能定位、使用场景、代码示例和注意事项四个维度展开帮助大家真正做到知其然更知其所以然在日常开发中让生产力成倍提升。需要说明的是注解本身并不会凭空产生魔法它们的本质依然是 JDK 提供的元数据标记真正发挥作用的是 Spring 容器背后的Bean 工厂、后置处理器和代理机制。因此理解注解不仅要知道「怎么用」还要理解它「为什么能生效」这样才能在遇到问题时快速定位并做出正确决策。二、启动与自动装配注解6 个这一类注解是整个 Spring Boot 应用的基石它们负责启动容器、扫描组件、开启自动配置。几乎所有 Spring Boot 项目的入口类和配置类都会用到它们。1. SpringBootApplicationSpringBootApplication 是 Spring Boot 项目中最核心、最常见的注解它标注在主启动类上。这个注解实际上是一个「三合一」的组合注解内部聚合了 SpringBootConfiguration、EnableAutoConfiguration 和 ComponentScan 三个注解的功能。也就是说当你写上 SpringBootApplication 时相当于同时完成了配置声明、自动配置开启和组件扫描三件事。import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }如果不想使用默认行为可以通过属性进行微调例如通过scanBasePackages指定扫描的根包通过exclude排除某些自动配置类。默认情况下组件扫描会以启动类所在的包为根路径因此启动类最好放在项目包结构的顶层避免出现扫描不到子包组件的问题。2. SpringBootConfigurationSpringBootConfiguration 是 Configuration 在 Spring Boot 中的语义别名表示当前类是一个配置类。它在官方文档中的定位很明确保留这个注解是为了让工具链如 Spring Boot 的测试支持能够更清晰地识别出「这是一个 Spring Boot 的配置类」而不是一个普通的 Spring 配置类。import org.springframework.boot.SpringBootConfiguration; SpringBootConfiguration public class AppConfig { // 这里可以声明 Bean }对绝大多数普通业务项目来说我们几乎不会单独手动使用 SpringBootConfiguration因为 SpringBootApplication 已经包含了它。但了解它的存在有助于我们在阅读 Spring Boot 源码、排查启动日志时理解底层机制。3. EnableAutoConfigurationEnableAutoConfiguration 是 Spring Boot 自动配置体系的核心开关。它的作用是告诉 Spring Boot根据当前 classpath 中的依赖、已注册的 Bean 以及各类条件判断自动完成框架组件的默认配置。例如只要引入了 spring-boot-starter-data-jpaSpring Boot 就会自动帮你配置好 DataSource、EntityManagerFactory、事务管理器等一连串基础设施。import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; Configuration EnableAutoConfiguration public class AutoConfigExample { }自动配置真正的执行者是AutoConfigurationImportSelector它会读取 classpath 下META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的配置类清单再结合 Conditional 条件注解决定哪些配置需要生效。这种按需装配的机制是 Spring Boot「约定优于配置」理念最典型的体现。4. ComponentScanComponentScan 用于指定组件扫描的包路径。Spring 容器会自动扫描指定包以及子包下被 Component、Service、Repository、Controller 等注解标记的类并把它们注册为 Spring Bean。import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; Configuration ComponentScan(basePackages {com.example.service, com.example.dao}) public class ScanConfig { }当启动类不在业务组件的上级包时需要显式通过 ComponentScan 指定包路径否则会出现 Bean 找不到的错误。在大型多模块项目中把不同模块的组件包显式列出来是一种更可控的做法。此外它的excludeFilters属性可以用来排除某些不需要注册的类。5. ConfigurationConfiguration 标记的类被称为配置类它的核心能力是替代传统的 XML 配置文件。被 Configuration 修饰的类中通过 Bean 注解声明的方法返回值会被注册到 Spring 容器中作为 Bean 供其他地方注入使用。import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class DataSourceConfig { Bean public MyDataSource myDataSource() { return new MyDataSource(jdbc:mysql://localhost:3306/demo); } }一个需要特别注意的细节是Configuration 类会被 CGLIB 增强为代理类因此在配置类内部调用 Bean 方法时Spring 保证返回的是容器中同一个单例 Bean而不会重复创建。而普通的 Component 类则不具备这种代理增强能力这一点在跨方法调用共享 Bean 时尤其重要。6. ImportImport 用于向容器中导入其他配置类或者普通类。它可以导入普通类、Configuration 配置类、ImportSelector 实现类以及 ImportBeanDefinitionRegistrar 实现类是很多底层框架扩展机制的入口。import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; Configuration Import({RedisConfig.class, MqConfig.class}) public class RootConfig { }当你需要把多个分散的配置类汇总到一处启用或者希望模块化组织配置时Import 非常有用。在 Spring Boot 自动配置的底层源码里Import 也被大量使用是理解框架扩展点必须掌握的一个注解。三、组件注册与分层注解7 个这一类注解用于把业务对象交给 Spring 容器管理并根据分层职责明确组件的角色。它们本质上做的都是同一件事——注册 Bean但不同的注解让代码意图更清晰也让工具链和 AOP 切面能更精准地识别目标。7. ComponentComponent 是通用的组件标记注解表示该类是一个 Spring 管理的 Bean。它是 Service、Repository、Controller 等注解的元注解也就是说这些注解内部都包含了 Component。对于那些不属于任何特定分层、但又需要容器管理的工具类或公共组件可以直接使用 Component。import org.springframework.stereotype.Component; Component public class SmsHelper { public void send(String phone, String content) { // 发送短信逻辑 } }虽然某个类硬要用 Service 也能正常工作但从代码可读性和团队规范角度出发建议按照类所处的层次选择最贴切的注解避免所有类都笼统地标注成 Component。8. ServiceService 标记的类代表业务层组件通常承载核心业务逻辑如订单处理、用户服务、权限计算等。它除了标识语义之外和 Component 在功能上完全相同但明确的业务语义可以帮助团队快速理解代码边界。import org.springframework.stereotype.Service; Service public class OrderService { public Order createOrder(Long userId, Long skuId) { // 创建订单业务逻辑 return new Order(userId, skuId); } }在分层架构中业务层应尽量只依赖 DAO 层接口和领域模型不要在 Service 类中直接处理 HTTP 请求参数或数据库连接细节。清晰的分层能让事务边界、异常处理和单元测试都更加简单。9. RepositoryRepository 标记的是数据访问层组件通常对应 DAO。它比 Component 多了一个非常实用的能力Spring 会把该组件抛出的数据访问异常统一转换为 Spring 的 DataAccessException 体系从而屏蔽不同持久化技术之间的异常差异。import org.springframework.stereotype.Repository; Repository public class UserRepository { public User findById(Long id) { // 通过 JDBC 或 JPA 查询用户 return null; } }当项目中混用 MyBatis、JPA 或 JDBC 时Repository 的异常翻译能力显得尤为重要它能让你在业务层用统一的异常处理逻辑应对底层不同的数据访问实现。10. ControllerController 是 Spring MVC 中控制器组件的标记注解用于处理 HTTP 请求并返回视图。它通常配合 RequestMapping 等注解使用。在使用传统服务端渲染如 Thymeleaf、JSP时Controller 方法返回的就是视图名或 ModelAndView。import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; Controller public class PageController { GetMapping(/hello) public String hello(Model model) { model.addAttribute(name, world); return hello; } }在现代前后端分离架构中大部分接口返回的是 JSON 数据而不是页面视图这种情况下 Controller 用得越来越少取而代之的是下面要介绍的 RestController。11. RestControllerRestController 是 Controller 和 ResponseBody 的组合注解。被它标记的类中所有方法的返回值都会直接作为响应体写回客户端而不会经过视图解析器。这个注解是 RESTful API 开发中使用频率最高的注解之一。import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; RestController public class UserApiController { GetMapping(/api/user) public User getUser() { return new User(1L, 张三); } }返回对象时Spring MVC 会通过 HttpMessageConverter默认使用 Jackson将 Java 对象序列化为 JSON。如果某个方法既想返回 JSON 又想返回视图的情况并不存在因此 RestController 与视图渲染是互斥的使用时要想清楚接口的定位。12. BeanBean 注解作用于方法上表示该方法的返回值会被注册为 Spring 容器中的 Bean。与方法内部自己 new 对象不同被 Bean 标注的方法由容器统一管理和维护能够参与依赖注入、生命周期回调以及 AOP 代理。import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class CacheConfig { Bean(name localCache) public Cache localCache() { return new LocalCache(1024); } }Bean 通常配合 Configuration 使用用于把第三方库的对象纳入 Spring 管理比如数据库连接池、RestTemplate、线程池、消息队列客户端等。可以用name或value指定 Bean 名称用initMethod和destroyMethod指定生命周期回调方法。13. MapperMapper 是 MyBatis 提供的注解用于标记 MyBatis 的 Mapper 接口。被标记后MyBatis 会为该接口生成动态代理实现并注册为 Spring Bean这样在 Service 中就可以直接通过 Autowired 注入并调用数据库操作方法无需手写实现类。import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; Mapper public interface UserMapper { Select(SELECT id, name FROM t_user WHERE id #{id}) User findById(Long id); }当项目中的 Mapper 数量很多时可以在启动类上使用 MapperScan 注解指定扫描包路径从而避免在每个接口上重复添加 Mapper。如果同时引入了 MyBatis-Plus通常还会配合其提供的 BaseMapper 接口进一步提升开发效率。四、依赖注入与配置读取注解7 个依赖注入是 Spring 的核心能力。这一部分注解负责把容器中的 Bean 自动装配到需要它的地方以及把外部配置文件的属性值注入到组件中大大减少手动获取实例和硬编码配置的工作量。14. AutowiredAutowired 是 Spring 最常用的自动装配注解默认按照类型byType从容器中查找匹配的 Bean 并完成注入。它可以用在构造方法、字段、Setter 方法甚至任意方法参数上。如果容器中同类型 Bean 只有一个注入过程会非常顺畅。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; Service public class OrderService { private final OrderMapper orderMapper; Autowired public OrderService(OrderMapper orderMapper) { this.orderMapper orderMapper; } }从 Spring 4.3 开始如果类只有一个构造方法构造方法上的 Autowired 可以省略。推荐优先使用构造方法注入配合 final 字段可以让依赖关系在对象创建时就确定下来也更有利于单元测试。当存在多个同类型 Bean 时需要结合 Qualifier 或 Primary 解决歧义。15. QualifierQualifier 用来解决「同一类型存在多个 Bean」时注入歧义问题。它可以和 Autowired 配合使用通过 Bean 名称精确指定要注入哪一个实现。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; Service public class PayService { Autowired Qualifier(alipay) private PayChannel payChannel; }在上面的示例中假设容器中存在 alipay 和 wechatPay 两个 PayChannel 实现只有配合 Qualifier 才能确定具体注入哪一个。Qualifier 也可以标注在自定义注解上形成更语义化的限定符比如 AlipayChannel、WechatChannel从而避免字符串魔法值散落在代码各处。16. ResourceResource 是 JDK JSR-250 规范提供的注入注解不属于 Spring 自有体系但 Spring 容器同样支持它。它默认按照名称byName进行注入如果没有指定 name 属性则先用字段名或属性名作为 Bean 名称去查找找不到时再退回按类型查找。import javax.annotation.Resource; import org.springframework.stereotype.Service; Service public class UserService { Resource private UserMapper userMapper; }Autowired 是 Spring 原生注解默认 byTypeResource 是 Java 标准注解默认 byName。两者在大多数简单场景下可以互换但如果有多个同类型 Bean就需要特别注意注入策略的差异。团队内最好统一注入风格避免混用造成理解成本。17. ValueValue 用于把外部配置值、常量或表达式注入到字段、方法参数中。最常用的做法是配合占位符${...}读取 application.yml 或 application.properties 中的配置项也可以用#{...}引用 SpEL 表达式。import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; Component public class FileUploadConfig { Value(${file.upload.max-size:10MB}) private String maxSize; Value(${server.port:8080}) private int port; }示例中的${file.upload.max-size:10MB}表示读取配置项 file.upload.max-size如果配置文件中不存在该键则使用默认值 10MB。Value 适合注入少量、离散的配置项当需要读取大量相关配置时建议改用下一节要讲的 ConfigurationProperties 做批量绑定。18. ConfigurationPropertiesConfigurationProperties 用于把配置文件中的一组属性批量绑定到一个 POJO 上。与 Value 的零散注入不同它按照前缀匹配规则自动将相同前缀下的所有配置映射为对象的字段
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑