外观
Spring Boot 常用注解
约 2696 字大约 9 分钟
2025-08-16
一、核心启动与配置注解
1. @SpringBootApplication
作用:组合了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan,是 Spring Boot 应用的启动注解。
典型用法:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}关键特性:
@Configuration:标识该类为配置类@EnableAutoConfiguration:启用 Spring Boot 自动配置@ComponentScan:扫描当前包及其子包下的组件
常用参数:
// 排除特定自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
// 自定义扫描包
@SpringBootApplication(scanBasePackages = "com.example.app")提示:这是每个 Spring Boot 应用必须的注解,通常放在主类上。
2. @Configuration
作用:标识该类为配置类,等同于 XML 配置文件。
典型用法:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}与 XML 对比:
<bean id="myService" class="com.example.MyServiceImpl"/>→@Bean方法<context:component-scan base-package="com.example"/>→@ComponentScan
提示:现代 Spring Boot 应用中,
@Configuration比 XML 配置更常用,更直观。
3. @ComponentScan
作用:指定 Spring 扫描组件的包路径。
典型用法:
// 扫描指定包
@ComponentScan("com.example.service")
// 多包扫描
@ComponentScan({"com.example.service", "com.example.repository"})常用参数:
| 参数 | 说明 |
|---|---|
basePackages | 指定要扫描的包 |
basePackageClasses | 指定包中某个类,扫描该类所在包 |
excludeFilters | 排除特定组件 |
includeFilters | 包含特定组件 |
提示:
@SpringBootApplication已经包含了@ComponentScan,默认扫描主类所在包及其子包,通常无需额外配置。
二、组件注册与依赖注入
1. 组件注册注解
四大核心组件注解:
| 注解 | 作用 | 适用场景 |
|---|---|---|
@Component | 通用组件 | 不好归类的普通组件 |
@Service | 业务层组件 | 服务层逻辑 |
@Repository | 数据访问组件 | DAO 层、Repository |
@Controller | 控制层组件 | MVC 控制器 |
使用示例:
// 业务服务
@Service
public class UserService {
// 业务逻辑
}
// 数据访问
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
// 控制器
@Controller
public class UserController {
// MVC 控制器
}
// 通用组件
@Component
public class UtilityComponent {
// 通用工具类
}提示:这四个注解本质相同,都是
@Component的特化,主要为了代码可读性和语义化。
2. 依赖注入注解
@Autowired:
@Service
public class UserService {
// 字段注入(不推荐)
@Autowired
private UserRepository userRepository;
// 构造器注入(推荐)
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// Setter注入
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}@Autowired 关键特性:
- 默认按类型注入
- 可设置
required = false允许依赖不存在 - 结合
@Qualifier按名称注入
@Qualifier:
@Component
@Qualifier("fileStorage")
public class FileStorageService implements StorageService { }
@Component
@Qualifier("dbStorage")
public class DbStorageService implements StorageService { }
@Service
public class DocumentService {
// 指定使用哪个实现
@Autowired
@Qualifier("fileStorage")
private StorageService storageService;
}@Resource:
@Service
public class UserService {
// 按名称注入(JSR-250标准)
@Resource(name = "userRepository")
private UserRepository userRepository;
}最佳实践:
- 优先使用构造器注入(保证不可变性和完全初始化)
- 避免字段注入(不利于测试和可维护性)
- 多个实现时使用
@Qualifier指定
三、配置与属性绑定
1. @Value
作用:注入配置属性值。
典型用法:
@Component
public class AppConfig {
// 注入简单属性
@Value("${app.name}")
private String appName;
// 设置默认值
@Value("${app.timeout:5000}")
private long timeout;
// 注入系统属性
@Value("${java.home}")
private String javaHome;
// 注入随机值
@Value("${random.uuid}")
private String uuid;
}支持的表达式:
${property}:引用属性${property:default}:带默认值的属性#{expression}:SpEL 表达式
提示:对于简单属性,
@Value很方便;但对于复杂对象,推荐使用@ConfigurationProperties。
2. @ConfigurationProperties
作用:类型安全的配置属性绑定。
典型用法:
@Component
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {
private String name;
private boolean enabled;
@Min(1000)
@Max(65535)
private int port;
private List<String> allowedIps = new ArrayList<>();
private Map<String, String> features = new HashMap<>();
// getters and setters
}配置文件:
app:
name: my-application
enabled: true
port: 8080
allowed-ips:
- "192.168.1.1"
- "10.0.0.1"
features:
dark-mode: true
notifications: false优势:
- 类型安全:编译时检查
- 支持数据验证(结合
@Validated) - IDE 支持:自动提示和跳转
- 支持松散绑定(如
allowedIps可配置为allowed-ips)
启用方式:
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class Application {
// ...
}提示:对于复杂配置,
@ConfigurationProperties比@Value更强大、更安全,是 Spring Boot 推荐的方式。
四、条件化配置
1. @ConditionalOnClass / @ConditionalOnMissingClass
作用:根据类路径中是否存在指定类来决定是否创建 Bean。
典型用法:
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DataSource dataSource() {
// 创建数据源
}
}使用场景:
- 仅当类路径中有 JdbcTemplate 时配置数据源
- 仅当存在 Redis 客户端时配置 Redis 缓存
2. @ConditionalOnProperty
作用:根据配置属性是否存在或特定值来决定是否创建 Bean。
典型用法:
@Configuration
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true", matchIfMissing = false)
public class FeatureConfiguration {
@Bean
public FeatureService featureService() {
return new FeatureServiceImpl();
}
}配置文件:
app:
feature:
enabled: true参数说明:
| 参数 | 说明 |
|---|---|
name | 属性名称 |
havingValue | 期望的属性值 |
matchIfMissing | 属性不存在时是否匹配(默认 false) |
3. @ConditionalOnBean / @ConditionalOnMissingBean
作用:根据容器中是否存在指定 Bean 来决定是否创建 Bean。
典型用法:
@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}使用场景:
- 提供默认实现,但允许用户自定义覆盖
- 按需创建 Bean,避免冲突
提示:这些条件注解是 Spring Boot 自动配置的核心,理解它们有助于理解 Spring Boot 的工作原理。
五、Web 开发相关注解
1. REST 控制器注解
@RestController:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}等价于:
@Controller
@ResponseBody
public class UserController { ... }常用组合:
@RestController+@RequestMapping:定义 REST 控制器@GetMapping/@PostMapping/@PutMapping/@DeleteMapping:HTTP 方法映射
2. 请求处理注解
@PathVariable:
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
return userService.findById(id);
}
// 自定义路径变量名
@GetMapping("/users/{userId}")
public User getUser(@PathVariable("userId") Long id) {
return userService.findById(id);
}@RequestParam:
@GetMapping("/users")
public List<User> getUsers(
@RequestParam(required = false, defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "10") int size) {
return userService.findPaginated(page, size);
}@RequestBody:
@PostMapping("/users")
public User createUser(@Valid @RequestBody User user) {
return userService.save(user);
}@RequestHeader:
@GetMapping("/users")
public List<User> getUsers(@RequestHeader("Authorization") String token) {
// 使用 token 验证
return userService.findAll();
}最佳实践:
- RESTful API 优先使用
@PathVariable处理资源标识 - 查询参数使用
@RequestParam - 请求体使用
@RequestBody - 验证请求体使用
@Valid
六、数据访问注解
1. JPA 相关注解
实体定义:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 50)
private String username;
@Column(unique = true)
private String email;
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
// getters and setters
}Repository 接口:
public interface UserRepository extends JpaRepository<User, Long> {
// 方法名查询
List<User> findByUsername(String username);
// 自定义查询
@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
List<User> findByEmailDomain(@Param("domain") String domain);
}2. 事务管理
@Transactional:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public User createUser(User user) {
// 业务逻辑
return userRepository.save(user);
}
@Transactional(readOnly = true)
public List<User> getAllUsers() {
return userRepository.findAll();
}
}关键属性:
| 属性 | 说明 | 默认值 |
|---|---|---|
value / transactionManager | 事务管理器名称 | "transactionManager" |
propagation | 传播行为 | Propagation.REQUIRED |
isolation | 隔离级别 | Isolation.DEFAULT |
timeout | 超时时间(秒) | -1(不超时) |
readOnly | 是否只读 | false |
rollbackFor | 指定回滚的异常类型 | Throwable.class |
noRollbackFor | 指定不回滚的异常类型 | 空 |
提示:服务层方法通常应该添加
@Transactional,特别是涉及多个数据库操作时。
七、测试相关注解
1. @SpringBootTest
作用:用于集成测试,加载完整的 Spring 应用上下文。
典型用法:
@SpringBootTest
class UserServiceIntegrationTest {
@Autowired
private UserService userService;
@Test
void testCreateUser() {
User user = new User("john", "john@example.com");
User savedUser = userService.createUser(user);
assertNotNull(savedUser.getId());
}
}常用参数:
| 参数 | 说明 |
|---|---|
classes | 指定配置类 |
webEnvironment | 指定 Web 环境(MOCK, RANDOM_PORT, DEFINED_PORT, NONE) |
properties | 覆盖配置属性 |
2. @MockBean / @SpyBean
作用:在测试中创建和注入模拟对象。
典型用法:
@SpringBootTest
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void getUserTest() throws Exception {
// 模拟服务行为
when(userService.findById(1L)).thenReturn(new User("john"));
// 执行请求
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("john"));
}
}@MockBean vs @SpyBean:
@MockBean:完全模拟,所有方法默认返回空值@SpyBean:部分模拟,保留原始行为,可选择性地模拟特定方法
3. @DataJpaTest
作用:针对 JPA 的测试,自动配置内存数据库和测试EntityManager。
@DataJpaTest
class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository userRepository;
@Test
void testFindByUsername() {
User user = new User("john", "john@example.com");
entityManager.persist(user);
User found = userRepository.findByUsername("john");
assertEquals(user, found);
}
}提示:合理使用这些测试注解可以大幅提高测试效率和覆盖率。
八、实用技巧与最佳实践
1. 注解组合技巧
创建自定义组合注解:
// 创建组合注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Scope("prototype")
public @interface PrototypeComponent {
}
// 使用组合注解
@PrototypeComponent
public class MyPrototypeBean {
// ...
}组合 REST 控制器:
// 创建组合注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}
// 使用组合注解
@RestController("/api/users")
public class UserController {
// ...
}2. 注解属性覆盖
使用 @AliasFor 实现属性覆盖:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Service("customUserService")
public class UserService { }3. 元注解应用
使用元注解创建自定义注解:
// 创建自定义事务注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30
)
public @interface AppTransactional { }
// 使用自定义事务注解
@AppTransactional
public void businessMethod() {
// ...
}4. 注解处理器
使用 @ComponentScan.Filter 控制组件扫描:
@ComponentScan(
excludeFilters = @Filter(
type = FilterType.ANNOTATION,
classes = MyExclude.class
)
)
public class AppConfig { }九、常见问题与解决方案
1. 注解不生效问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
@Autowired 不生效 | 组件未被扫描到 | 检查包扫描路径,确保组件在扫描范围内 |
@Transactional 不生效 | 事务管理器未配置 | 添加 @EnableTransactionManagement |
| 自调用问题 | 避免在同一个类中调用事务方法 | |
| 代理问题 | 确保调用来自外部对象 | |
@ConfigurationProperties 不绑定 | 未启用 | 添加 @EnableConfigurationProperties 或使用 @Component |
| 前缀不匹配 | 检查 prefix 与配置文件中的前缀是否一致 |
2. 循环依赖问题
典型场景:
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Service
public class ServiceB {
@Autowired
private ServiceA serviceA;
}解决方案:
使用构造器注入 +
@Lazy@Service public class ServiceA { private final ServiceB serviceB; @Autowired public ServiceA(@Lazy ServiceB serviceB) { this.serviceB = serviceB; } }重构代码,消除循环依赖
使用 Setter 注入(不推荐)
提示:循环依赖通常是设计问题的信号,应优先考虑重构而非使用技术手段解决。
十、常用注解速查表
| 类别 | 注解 | 用途 | 使用频率 |
|---|---|---|---|
| 核心 | @SpringBootApplication | 应用启动 | ⭐⭐⭐⭐⭐ |
| 核心 | @Configuration | 配置类 | ⭐⭐⭐⭐ |
| 核心 | @ComponentScan | 组件扫描 | ⭐⭐⭐ |
| 组件 | @Component | 通用组件 | ⭐⭐⭐⭐ |
| 组件 | @Service | 服务层组件 | ⭐⭐⭐⭐⭐ |
| 组件 | @Repository | 数据访问组件 | ⭐⭐⭐⭐ |
| 组件 | @Controller | 控制器 | ⭐⭐⭐ |
| 依赖注入 | @Autowired | 自动注入 | ⭐⭐⭐⭐⭐ |
| 依赖注入 | @Qualifier | 指定名称注入 | ⭐⭐⭐ |
| 依赖注入 | @Resource | JSR-250 注入 | ⭐⭐ |
| 配置 | @Value | 注入简单属性 | ⭐⭐⭐⭐ |
| 配置 | @ConfigurationProperties | 类型安全配置 | ⭐⭐⭐⭐ |
| 条件 | @ConditionalOnClass | 类存在条件 | ⭐⭐⭐ |
| 条件 | @ConditionalOnProperty | 属性条件 | ⭐⭐⭐ |
| 条件 | @ConditionalOnMissingBean | Bean不存在条件 | ⭐⭐⭐ |
| Web | @RestController | REST控制器 | ⭐⭐⭐⭐⭐ |
| Web | @RequestMapping | 请求映射 | ⭐⭐⭐⭐⭐ |
| Web | @GetMapping | GET请求映射 | ⭐⭐⭐⭐⭐ |
| Web | @PathVariable | 路径变量 | ⭐⭐⭐⭐ |
| Web | @RequestParam | 请求参数 | ⭐⭐⭐⭐ |
| Web | @RequestBody | 请求体 | ⭐⭐⭐⭐ |
| 数据 | @Entity | JPA实体 | ⭐⭐⭐ |
| 数据 | @Table | 表映射 | ⭐⭐⭐ |
| 数据 | @Id | 主键 | ⭐⭐⭐ |
| 数据 | @Column | 列映射 | ⭐⭐⭐ |
| 数据 | @Transactional | 事务管理 | ⭐⭐⭐⭐ |
| 测试 | @SpringBootTest | 集成测试 | ⭐⭐⭐⭐ |
| 测试 | @MockBean | 模拟Bean | ⭐⭐⭐⭐ |
| 测试 | @DataJpaTest | JPA测试 | ⭐⭐⭐ |
