Spring Boot常用注解详解与最佳实践指南
- 发布时间:2025-03-20 16:53:46
- 本文热度:浏览 68 赞 0 评论 0
- 文章标签: Spring Boot Java开发 后端技术
- 全文共1字,阅读约需1分钟
一、核心启动与配置注解
1.1 @SpringBootApplication
作为Spring Boot项目的基石注解,@SpringBootApplication实际上是一个组合注解,包含三个核心功能:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
// 参数配置
}
实际应用示例:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
关键参数说明:
- scanBasePackages:自定义组件扫描路径
- exclude:显式禁用特定自动配置类
- proxyBeanMethods:控制Bean代理方式(Spring Boot 2.2+)
1.2 @Configuration
定义配置类的核心注解,通常与@Bean配合使用:
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
@Bean
@Profile("dev")
public CacheManager localCache() {
return new SimpleCacheManager();
}
}
1.3 @Conditional系列注解
条件化Bean创建的核心机制:
注解名称 | 生效条件 |
---|---|
@ConditionalOnClass | 类路径存在指定类时生效 |
@ConditionalOnMissingBean | 容器中不存在指定Bean时生效 |
@ConditionalOnProperty | 配置参数满足条件时生效 |
@ConditionalOnWebApplication | Web环境运行时生效 |
示例代码:
@Configuration
@ConditionalOnClass(DataSource.class)
public class DatabaseAutoConfiguration {
// 数据库相关自动配置
}
二、依赖注入相关注解
2.1 @Autowired
自动装配的三种主要方式:
// 字段注入
@Component
public class OrderService {
@Autowired
private PaymentService paymentService;
}
// 构造函数注入
@Component
public class OrderService {
private final PaymentService paymentService;
@Autowired
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
// Setter方法注入
@Component
public class OrderService {
private PaymentService paymentService;
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
最佳实践建议:
- 优先使用构造函数注入
- 需要处理循环依赖时使用@Lazy
- 多实现时配合@Qualifier使用
2.2 @Qualifier
解决同一接口多个实现的注入问题:
public interface MessageService {
void send();
}
@Component("smsService")
public class SmsService implements MessageService {
// 实现
}
@Component("emailService")
public class EmailService implements MessageService {
// 实现
}
@Service
public class NotificationService {
private final MessageService messageService;
@Autowired
public NotificationService(@Qualifier("emailService") MessageService messageService) {
this.messageService = messageService;
}
}
2.3 @Primary
定义首选的Bean实现:
@Configuration
public class CacheConfig {
@Bean
@Primary
public CacheManager redisCache() {
return new RedisCacheManager();
}
@Bean
public CacheManager localCache() {
return new SimpleCacheManager();
}
}
三、Web开发相关注解
3.1 @RestController
组合了@Controller和@ResponseBody的便捷注解:
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}
3.2 请求映射注解
完整的请求映射类型:
注解 | HTTP方法 | 等价快捷方式 |
---|---|---|
@RequestMapping | 通用 | - |
@GetMapping | GET | @RequestMapping(method=GET) |
@PostMapping | POST | 同上 |
@PutMapping | PUT | 同上 |
@DeleteMapping | DELETE | 同上 |
@PatchMapping | PATCH | 同上 |
路径参数处理示例:
@GetMapping("/orders/{orderId}/items/{itemId}")
public OrderItem getOrderItem(
@PathVariable Long orderId,
@PathVariable String itemId,
@RequestParam(defaultValue = "false") boolean detail) {
// 业务逻辑
}
3.3 参数绑定注解
@PostMapping("/search")
public List<User> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestBody SearchFilter filter) {
// 分页查询逻辑
}
3.4 全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFound(ResourceNotFoundException ex) {
return new ErrorResponse(ex.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> handleValidation(MethodArgumentNotValidException ex) {
return ex.getBindingResult()
.getFieldErrors()
.stream()
.collect(Collectors.toMap(
FieldError::getField,
FieldError::getDefaultMessage
));
}
}
四、数据访问相关注解
4.1 JPA注解
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String name;
@Enumerated(EnumType.STRING)
private Department department;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
private List<Task> tasks = new ArrayList<>();
@Version
private Long version;
// 省略getter/setter
}
4.2 事务管理
@Service
@Transactional
public class OrderService {
@Transactional(readOnly = true)
public Order getOrder(Long id) {
return orderRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Order not found"));
}
@Transactional(rollbackFor = Exception.class)
public Order createOrder(Order order) {
// 业务逻辑
return orderRepository.save(order);
}
}
事务传播行为示例:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void auditLog(Action action) {
// 审计日志记录
}
五、配置与属性绑定
5.1 @Value
类型安全的配置注入:
@Component
public class AppConfig {
@Value("${app.timeout:3000}")
private int timeout;
@Value("${app.servers}")
private List<String> servers;
@Value("classpath:config/default.json")
private Resource defaultConfig;
}
5.2 @ConfigurationProperties
批量配置绑定:
@ConfigurationProperties(prefix = "app.mail")
@Validated
public class MailProperties {
@NotBlank
private String host;
@Min(1025)
@Max(65535)
private int port;
private boolean sslEnabled = true;
// 省略getter/setter
}
注册配置类:
@SpringBootApplication
@EnableConfigurationProperties(MailProperties.class)
public class DemoApplication {
// 启动类
}
六、测试相关注解
6.1 单元测试
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@InjectMocks
private OrderService orderService;
@Test
void shouldCreateOrderSuccessfully() {
// Mock设置
when(orderRepository.save(any())).thenReturn(new Order());
// 测试执行
Order result = orderService.createOrder(new Order());
// 验证
assertNotNull(result);
verify(orderRepository).save(any());
}
}
6.2 集成测试
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void shouldReturnUserWhenExists() throws Exception {
User mockUser = new User(1L, "test");
when(userService.findById(1L)).thenReturn(mockUser);
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("test"));
}
}
七、高级特性注解
7.1 定时任务
@Configuration
@EnableScheduling
public class ScheduleConfig {
@Scheduled(fixedRate = 5000)
public void reportStatus() {
// 每5秒执行
}
@Scheduled(cron = "0 0 2 * * ?")
public void dailyCleanup() {
// 每天凌晨2点执行
}
}
7.2 异步处理
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.initialize();
return executor;
}
}
@Service
public class ReportService {
@Async
public CompletableFuture<Report> generateReport() {
// 长时间报表生成逻辑
return CompletableFuture.completedFuture(new Report());
}
}
7.3 缓存管理
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("products");
}
}
@Service
public class ProductService {
@Cacheable(value = "products", key = "#id")
public Product getProduct(Long id) {
// 数据库查询
}
@CachePut(value = "products", key = "#product.id")
public Product updateProduct(Product product) {
// 更新逻辑
}
@CacheEvict(value = "products", allEntries = true)
public void clearCache() {
// 清空缓存
}
}
八、自定义注解开发
8.1 创建组合注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.OK)
public @interface AdminOnly {
String value() default "";
}
8.2 实现注解处理器
@Aspect
@Component
public class LogExecutionTimeAspect {
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
return proceed;
}
}
// 使用自定义注解
@Service
public class DataProcessor {
@LogExecutionTime
public void processData() {
// 复杂数据处理逻辑
}
}
正文到此结束
相关文章
热门推荐
评论插件初始化中...