12.1 — 注解体系速查
定位: SpringBoot 全栈注解按层分类速查 — 启动/Web/数据/测试全覆盖 面试高频度: ⭐⭐⭐⭐⭐ 考查方式: @SpringBootApplication 拆解、@Transactional 失效、注解作用域辨析
一、按层速查
┌─────────────────────────────────────────────────────────────┐
│ SpringBoot 注解分层全景 │
│ │
│ ┌─────────── 启动与配置 ──────────────────────┐ │
│ │ @SpringBootApplication @Configuration │ │
│ │ @Bean @ComponentScan @EnableAutoConfig │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────── Controller 层 ──────────────────────┐ │
│ │ @RestController @RequestMapping │ │
│ │ @GetMapping @PostMapping @PutMapping │ │
│ │ @RequestParam @PathVariable @RequestBody │ │
│ │ @RestControllerAdvice @ExceptionHandler │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────── Service 层 ──────────────────────────┐ │
│ │ @Service @Transactional │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────── Mapper/Repository 层 ───────────────┐ │
│ │ @Repository @Mapper @MapperScan │ │
│ │ @Select @Insert @Update @Delete @Param │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌─────────── 测试层 ─────────────────────────────┐ │
│ │ @SpringBootTest @WebMvcTest @DataJpaTest │ │
│ │ @MockBean @Mock @InjectMocks │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘二、启动与配置类注解
@SpringBootApplication
java
@SpringBootApplication // 等价于以下三个注解的组合
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}| 组合注解 | 作用 |
|---|---|
| @Configuration | 标记为 Java Config 配置类 |
| @EnableAutoConfiguration | 开启自动配置(核心!) |
| @ComponentScan | 扫描 @Component/@Service/@Repository/@Controller |
@EnableAutoConfiguration 原理:
java
// 通过 @Import(AutoConfigurationImportSelector.class) 导入
// → 加载 META-INF/spring.factories 中配置的自动配置类
// → 按 @ConditionalOnXxx 条件判断是否生效条件装配(@Conditional 系列)
| 注解 | 条件 |
|---|---|
| @ConditionalOnClass | 类路径中存在指定类 |
| @ConditionalOnMissingClass | 类路径中不存在指定类 |
| @ConditionalOnBean | 容器中存在指定 Bean |
| @ConditionalOnMissingBean | 容器中不存在指定 Bean |
| @ConditionalOnProperty | 配置项存在且等于指定值 |
| @ConditionalOnExpression | SpEL 表达式为 true |
三、Controller 层注解
映射注解
| 注解 | 等价于 | 说明 |
|---|---|---|
| @RestController | @Controller + @ResponseBody | 返回 JSON(常用) |
| @Controller | — | 返回视图(前后端未分离时) |
| @RequestMapping | — | 通用映射(method 可指定全部方法) |
| @GetMapping | @RequestMapping(method=GET) | — |
| @PostMapping | @RequestMapping(method=POST) | — |
| @PutMapping | @RequestMapping(method=PUT) | — |
| @DeleteMapping | @RequestMapping(method=DELETE) | — |
参数绑定注解
java
@RestController
@RequestMapping("/api/users")
public class UserController {
// @RequestParam — 查询参数
@GetMapping
public List<User> list(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size) { }
// @PathVariable — 路径参数
@GetMapping("/{id}")
public User get(@PathVariable Long id) { }
// @RequestBody — JSON 请求体
@PostMapping
public User create(@RequestBody @Valid User user) { }
// @RequestHeader — 请求头
@GetMapping("/header")
public String header(@RequestHeader("User-Agent") String ua) { }
}全局异常处理
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public Result handleIllegalArg(IllegalArgumentException e) {
return Result.error(400, e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result handleAll(Exception e) {
return Result.error(500, "服务器内部错误");
}
}四、Service 与事务层
@Transactional 详解
java
@Service
public class UserService {
@Transactional(propagation = Propagation.REQUIRED, // 默认:支持当前事务,不存在则新建
isolation = Isolation.READ_COMMITTED, // 读已提交
rollbackFor = Exception.class, // 默认只回滚 RuntimeException
timeout = 30) // 超时秒数
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// ... 数据库操作
}
}事务传播行为:
| 传播行为 | 说明 |
|---|---|
| REQUIRED (默认) | 有则加入,无则新建 |
| REQUIRES_NEW | 总是新建,挂起当前事务 |
| SUPPORTS | 有则加入,无则非事务执行 |
| NOT_SUPPORTED | 非事务执行,挂起当前事务 |
| MANDATORY | 必须在事务中,否则抛异常 |
| NEVER | 不能在事务中,否则抛异常 |
| NESTED | 嵌套事务(JDBC Savepoint) |
五、Mapper/Repository 层
MyBatis 注解
java
@Mapper // 标记为 MyBatis Mapper 接口
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(@Param("id") Long id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE users SET name = #{name} WHERE id = #{id}")
int update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
int delete(Long id);
}六、配置类与 Bean
java
@Configuration
@PropertySource("classpath:app.properties") // 加载自定义配置
public class AppConfig {
@Value("${app.name}") // 注入配置值
private String appName;
@Bean // 声明 Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@ConfigurationProperties(prefix = "app.datasource") // 配置属性绑定
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}七、面试视角
| 追问 | 答案要点 |
|---|---|
| @SpringBootApplication 包含哪些注解? | @Configuration + @EnableAutoConfiguration + @ComponentScan |
| 自动配置的原理? | spring.factories → AutoConfigurationImportSelector → @ConditionalOnXxx |
| @Transactional 失效场景? | 非 public、this 调用、try-catch 异常未抛出、传播行为不当 |
| @Autowired 和 @Resource 区别? | @Autowired 按类型注入(Spring);@Resource 按名称注入(Java 标准) |
| @Component 和 @Bean 区别? | @Component 作用于类(自动扫描);@Bean 作用于方法(手动声明) |
📚 相关链接
- **注解体系** — 注解底层机制
- **MyBatis索引** — MyBatis 整合
- **SpringBoot测试** — SpringBoot 测试
- ← 返回 **SpringBoot索引**