🌟 Spring Boot 注解大全(超级详细完整版)
🧩 第一类:应用入口注解
1. @SpringBootApplication
✅ 定义与作用
这是 Spring Boot 应用的核心注解,是一个组合注解,整合了以下三个注解:
@Configuration:声明当前类是一个配置类,相当于一个 Spring 的 XML 配置文件;
@EnableAutoConfiguration:启动 Spring Boot 的自动配置功能,根据当前项目的依赖情况自动配置应用;
@ComponentScan:自动扫描当前类所在包及其子包下所有带注解的类(如@Controller,@Service等),并注册为 Spring Bean。
✅ 使用位置
只能用于主类(程序启动入口)上。
✅ 实际示例
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
✅ 工作机制详解
- Spring Boot 启动时,会从
META-INF/spring.factories中加载所有自动配置类;
- 每个自动配置类上带有
@Conditional系列注解,控制其是否启用(如是否存在某类、是否配置某属性等);
- 常见自动配置类如
DataSourceAutoConfiguration,WebMvcAutoConfiguration等。
✅ 进阶应用
可使用如下形式排除某些不需要的自动配置类:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
⚠️ 注意事项
- 启动类一定要放在根包,以确保能扫描到所有子包的组件;
- 自动配置不是万能的,有时需要我们手动补充配置;
❗常见误区
| 问题 | 错误示例 | 正确说明 |
| 启动类放在子包 | com.example.controller.App | 建议放在 com.example.MyApp |
| 忘记写注解 | public class App { ... } | 必须加 @SpringBootApplication 才能使用自动配置 |
🎓 面试扩展问题
Q1. @SpringBootApplication 内部都包含哪些注解?
答:包含 @Configuration, @EnableAutoConfiguration, @ComponentScan。
Q2. 自动配置是如何实现的?
答:Spring Boot 利用 spring.factories 文件通过 SPI 机制加载自动配置类(如 WebMvcAutoConfiguration),这些类本质上是带有 @Configuration 的 Java 配置类,在特定条件下被激活。
Q3. 如何禁止某些自动配置?
答:使用 exclude 参数或添加 spring.autoconfigure.exclude 属性。
🧩 第二类:组件注册注解
2. @Component
✅ 定义
表示这是一个 Spring 管理的通用组件,最基础的注解形式。
✅ 适用位置
用于类上,Spring 会自动将其加入 ApplicationContext 容器。
✅ 示例
@Component
public class EmailSender {
public void send() {
System.out.println("Send email");
}
}
✅ 说明
所有其他如 @Service, @Controller, @Repository 都是 @Component 的语义化变种。
🎓 面试拓展
Q. @Component 和 @Bean 的区别?
答:@Component 注解是自动扫描的方式创建 Bean,@Bean 是通过 Java 配置类手动注册。
3. @Service
✅ 定义与作用
表示这是业务逻辑层的组件,是 @Component 的语义化封装,主要用于标识 service 层的类。
✅ 示例
@Service
public class OrderService {
public void placeOrder() {
// 下单逻辑
}
}
✅ 区别说明
与 @Component 功能相同,但 @Service 语义更清晰,有助于分层架构识别。
🎓 面试拓展
Q. @Service 注解的作用除了注册 Bean 外还有什么?
答:除了注册为 Spring Bean,还用于让开发者、工具、文档清楚地知道该类是“业务层”的组件,有利于开发规范和分层理解。
4. @Repository
✅ 定义与作用
用于标识 DAO(数据访问对象)层的组件。Spring 会对其方法抛出的异常进行数据访问异常转换(封装为 DataAccessException)。
✅ 示例
@Repository
public class UserRepository {
public void save(User user) {
// 数据库存储逻辑
}
}
✅ 异常处理说明
在使用 Spring Data 或 JdbcTemplate 时,@Repository 能自动将底层 JDBC 异常转换成统一的 Spring 异常体系。
🎓 面试拓展
Q. @Repository 和 @Mapper 的区别?
答:@Repository 是 Spring 的注解,适用于所有持久层组件;而 @Mapper 是 MyBatis 提供的注解,用于自动扫描映射接口。
5. @Controller
✅ 定义与作用
这是用于 MVC 控制层的注解,表示该类是前端控制器,用于返回视图(非 JSON 的页面)。
✅ 示例
@Controller
public class PageController {
@GetMapping("/hello")
public String hello() {
return "hello.html";
}
}
✅ 注意事项
如果希望方法返回 JSON 数据而不是页面内容,应改为使用 @RestController。
6. @RestController
✅ 定义
组合注解,等价于 @Controller + @ResponseBody,返回结果直接作为 HTTP 响应体输出(通常为 JSON)。
✅ 示例
@RestController
public class ApiController {
@GetMapping("/api/hello")
public String sayHello() {
return "Hello, API";
}
}
🎓 面试拓展
Q. @Controller 和 @RestController 有什么区别?
答:@RestController 的所有方法返回值都会自动进行序列化(如 JSON);而 @Controller 通常返回视图,需要配合 @ResponseBody 使用才能返回数据。
🧩 第三类:依赖注入注解
7. @Autowired
✅ 定义
@Autowired 是 Spring 提供的自动依赖注入注解,默认按类型注入。
✅ 使用方式
- 可以注解在字段、构造方法、Setter 方法、参数上。
- 默认情况下,字段必须在容器中存在,否则抛出异常。
✅ 示例
@Autowired
private UserService userService;✅ 构造器注入
@Autowired
public MyController(UserService userService) {
this.userService = userService;
}✅ 可选注入
@Autowired(required = false)
private SomeService optionalService;🎓 面试拓展
Q:为什么推荐构造方法注入?
答:构造方法注入有利于测试和保证依赖不可变性(final 修饰),可以检测循环依赖。
8. @Qualifier
✅ 定义
配合 @Autowired 使用,按名称注入。
✅ 示例
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;🎓 面试拓展
Q:什么时候用 @Qualifier?
答:当有多个实现类时,@Autowired 无法判断注入哪个,此时使用 @Qualifier 指定 Bean 名称。
9. @Resource
✅ 定义
JSR-250 提供的标准注解,默认按名称注入,找不到再按类型。
✅ 示例
@Resource(name = "userService")
private UserService userService;✅ 与 @Autowired 区别
| 特点 | @Autowired | @Resource |
| 默认注入方式 | 按类型 | 按名称 |
| 是否为 Spring 原生 | 是 | 否(JSR 标准) |
10. @Inject
✅ 定义
JSR-330 提供的注解,功能类似 @Autowired。
✅ 注意事项
- 与
@Autowired类似,但不支持 Spring 的required=false属性。
- 用得较少,通常推荐使用
@Autowired。
🧩 第五类:Web 请求映射注解
15. @RequestMapping
✅ 定义
通用请求映射注解,可以用于类或方法上,支持 GET、POST、PUT、DELETE 等方法。
✅ 示例
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser() {
return "Tom";
}
}🎓 面试拓展
Q:如何实现 RESTful 风格的接口?
答:使用 @GetMapping, @PostMapping 等组合注解更语义化。
16. @GetMapping, @PostMapping 等
✅ 定义
是 @RequestMapping 的快捷注解,专用于具体 HTTP 方法。
✅ 示例
@GetMapping("/users")
public List<User> getAll() { ... }
@PostMapping("/users")
public void createUser(@RequestBody User user) { ... }17. @PathVariable
✅ 定义
用于从 URI 路径中提取参数。
✅ 示例
@GetMapping("/user/{id}")
public User getById(@PathVariable("id") Long id) { ... }18. @RequestParam
✅ 定义
获取 URL 查询参数,或表单参数。
✅ 示例
@GetMapping("/search")
public List<User> search(@RequestParam String keyword) { ... }19. @RequestBody
✅ 定义
将请求体(JSON)自动绑定到对象。
✅ 示例
@PostMapping("/add")
public void add(@RequestBody User user) { ... }✅ 注意事项
只适用于 POST、PUT 等包含请求体的方法。
20. @ResponseBody
✅ 定义
返回值将直接作为 HTTP 响应体内容(通常为 JSON)。
✅ 示例
@ResponseBody
@GetMapping("/time")
public LocalDateTime getTime() {
return LocalDateTime.now();
}21. @CrossOrigin
✅ 定义
用于解决跨域请求问题。
✅ 示例
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/data")
public Data getData() { ... }🧩 第六类:生命周期注解
22. @PostConstruct
✅ 定义
在 Bean 初始化完成后自动调用的方法。
✅ 示例
@Component
public class InitExample {
@PostConstruct
public void init() {
System.out.println("Bean 初始化完成后执行");
}
}✅ 使用场景
- 用于初始化数据、加载缓存、检查配置等。
23. @PreDestroy
✅ 定义
在 Spring 容器销毁前自动调用的方法。
✅ 示例
@PreDestroy
public void destroy() {
System.out.println("容器销毁前执行清理操作");
}✅ 使用场景
- 资源清理、关闭连接池、释放线程等。
🧩 第七类:测试注解
24. @SpringBootTest
✅ 定义
用于测试类上,启动完整 Spring Boot 上下文环境。
✅ 示例
@SpringBootTest
public class MyAppTest {
@Autowired
private MyService service;
}🎓 面试拓展
Q:它和 @WebMvcTest 的区别?
答:@SpringBootTest 加载整个应用,适合集成测试;@WebMvcTest 只加载 Controller。
25. @WebMvcTest
✅ 定义
仅用于 Web 层测试(Controller),不加载 Service 和 Repository。
✅ 示例
@WebMvcTest(MyController.class)
public class ControllerTest {
@Autowired
private MockMvc mockMvc;
}26. @DataJpaTest
✅ 定义
仅加载 JPA 相关组件(Entity、Repository),用于测试持久层。
✅ 示例
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private UserRepository repo;
}🧩 第八类:数据库相关注解
27. @Mapper
✅ 定义
MyBatis 提供,表示该接口是 Mapper,供 MyBatis 自动实现。
✅ 示例
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
List<User> findAll();
}28. @Select, @Insert, @Update, @Delete
✅ 示例
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(int id);✅ 注意事项
- 适合小型项目;
- 大型系统推荐使用 XML 管理 SQL。
29. @Entity
✅ 定义
JPA 注解,标识该类为实体类。
✅ 示例
@Entity
public class User {
@Id
private Long id;
private String name;
}30. @Table(name = "user")
✅ 定义
设置实体对应的表名,若不设置默认类名小写。
31. @Id
✅ 定义
主键注解,用于标识主键字段。
32. @GeneratedValue
✅ 定义
主键生成策略,可选值:AUTO、IDENTITY、SEQUENCE、TABLE。
🧩 第九类:AOP 注解
33. @Aspect
✅ 定义
用于定义一个切面类,结合 @Component 使用。
✅ 示例
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example..*Service.*(..))")
public void logBefore() {
System.out.println("执行前");
}
}34. @Before, @After, @Around, @AfterReturning, @AfterThrowing
✅ 示例
@Before("execution(* com.example..*Service.*(..))")
public void beforeAdvice() {}
@Around("execution(* com.example..*Controller.*(..))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前");
Object result = pjp.proceed();
System.out.println("环绕后");
return result;
}🧩 第十类:条件配置注解
35. @Conditional
✅ 定义
在特定条件下注册 Bean,通常与自定义条件类配合使用。
36. @Profile
✅ 定义
根据环境变量激活指定配置。
✅ 示例
@Profile("dev")
@Bean
public DataSource devDataSource() {
return new HikariDataSource();
}🧩 第十一类:异步与定时注解
37. @Async
✅ 定义
启用异步执行方法,需搭配 @EnableAsync。
38. @Scheduled
✅ 定义
用于定时任务,支持 cron 表达式、fixedRate、fixedDelay。
✅ 示例
@Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
public void task() {}🧩 第十二类:Spring Security 注解
39. @EnableWebSecurity
✅ 定义
开启 Web 安全配置。
40. @PreAuthorize
✅ 定义
方法执行前进行权限检查,基于表达式。
✅ 示例
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser() {}41. @Secured
✅ 定义
指定方法只允许某些角色访问。
✅ 示例
@Secured("ROLE_USER")
public void view() {}🧩 第十三类:自定义注解(进阶)
✅ 定义方式
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecution {
String value() default "";
}✅ 配合切面使用
@Aspect
@Component
public class LogAspect {
@Before("@annotation(logExecution)")
public void before(LogExecution logExecution) {
System.out.println("日志注解内容:" + logExecution.value());
}
}