大数跨境
0
0

强大!Spring Boot 9个宝藏注解,提升你的代码水平

强大!Spring Boot 9个宝藏注解,提升你的代码水平 Spring全家桶实战案例
2025-09-26
0
导读:绝了!Spring Boot 9个宝藏注解,提升你的代码水平
Spring Boot 3实战案例锦集PDF电子书已更新至130篇!
图片

🎉🎉《Spring Boot实战案例合集》目前已更新176个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

在日常开发中,我们常常只熟悉 Spring Boot 的基础注解,却忽略了那些能大幅提升代码质量与可维护性的“宝藏”功能。这些注解不仅简化了配置、增强了类型安全,还让应用更具弹性与可读性。掌握这些隐藏却强大的注解,是进阶 Spring Boot 高手的必经之路。本篇文章精选 9 个实用又易被忽视的注解,涵盖条件化配置、事件驱动、不可变配置等核心场景,助你写出更优雅、更健壮的代码。

2.实战案例

2.1 强大的SpEL条件注解@ConditionalOnExpression

相比@ConditionalOnProperty 条件判断相对简单直接;@ConditionalOnExpression 则不同,它凭借 SpEL 可综合多因素,如属性、方法结果等,构建复杂逻辑,比前者具备更强大的配置能力。

@Configuration@ConditionalOnExpression("${app.cache.enabled:false} and '${spring.profiles.active}' != 'test'")public class CacheConfiguration {  @Bean  CacheManager cacheManager() {    return new ConcurrentMapCacheManager() ;  }}

在这个示例中,我们创建了一个条件化的缓存配置,该配置仅在特定情况下才会生效。SpEL 表达式检查两个条件:

  • ${app.cache.enabled:false}验证 application.properties 中是否启用了缓存功能(如果未指定,则默认为 false)

  • '${spring.profiles.active}' != 'test':确保当前所处的环境不是测试(test)环境

你还可以调用其它的Bean方法

@Configuration@ConditionalOnExpression("@featureChecker.isAdvancedFeatureAvailable()")public class AdvancedFeatureConfig {}

只有featureChecker bean的isAdvancedFeatureAvailable方法返回true才会生效。

2.2 @ConstructorBinding 实现不可变配置

告别可变的配置属性!在 Spring Boot 中,将 @ConfigurationProperties 与 @ConstructorBinding 结合使用,可以创建不可变(immutable)的配置类,从而提升应用的安全性、线程安全性和代码的可维护性。

@ConfigurationProperties(prefix = "pack.app")@ConstructorBindingpublic class AppProperties {  private final Boolean enabled;  private final String apiKey;  private final String title;  private final String version;  public AppProperties(Boolean enabled, String apiKey,    String title, String version) {    this.enabled = enabled;    this.apiKey = apiKey;    this.title = title ;    this.version = version ;  }  // 这只会有getters方法}
  • @ConstructorBinding 确保所有属性在对象创建期间被设置

  • 使用 final 字段可防止初始化后被意外修改

  • List.copyOf() 创建允许的源列表的不可变副本 

  • 缺少 setter 方法保证了不可变性。

2.3 @EventListener 实现高级事件处理

@EventListener 的高级特性,事件驱动架构变得更加优雅:

@Componentpublic class OrderProcessorListener {
  @EventListener(condition = "#event.total > 1000")  @Order(1)  public void processLargeOrder(OrderCreatedEvent event) {    logger.info("处理订单【{}】, 总金额: {}", event.getOrderId(), event.getTotal());    // TODO  }}

condition 属性根据订单金额过滤事件,只有订单总额超过1000才会被处理。

2.4 @Lazy解决循环依赖

@Servicepublic class CartService {  private final OrderService orderService;  public CartService(@Lazy OrderService orderService) {    this.orderService = orderService;  }  public void checkout(Long cartId) {    // 处理结账    orderService.createOrder(cartId);  }}@Servicepublic class OrderService {  private final CartService cartService;  public OrderService(CartService cartService) {    this.cartService = cartService;  }  public void cancelOrder(Long orderId) {    // 恢复购物车    cartService.restoreCart(orderId);  }}
  • CartService(购物车服务)依赖于OrderService(订单服务),反之亦然。

  • @Lazy注解通过创建一个代理来打破这种依赖循环。

  • 实际的OrderService bean 仅在首次被使用时才会创建。

  • 这种模式应谨慎使用,因为循环依赖通常表明存在设计问题。

2.5 使用 @EnableConfigurationProperties 自动配置属性

@EnableConfigurationProperties({  DatabaseProperties.class,  CacheProperties.class})@Configurationpublic class AppConfig {  @Bean  DataSource dataSource(DatabaseProperties props) {    return DataSourceBuilder.create()      .url(props.getUrl())      .username(props.getUsername())      .password(props.getPassword())      .build();  }}
  • @EnableConfigurationProperties 会自动注册属性类可以一次性启用多个属性类

  • 属性会自动注入到需要它们的 bean 中

  • 为配置管理提供了一个集中化的位置

2.6 @Profile 进行配置表达式

@Bean  @Profile("prod")  public DataSource prodDataSource() {    return new ProductionDataSource();  }  @Bean  @Profile("dev | test")  public DataSource devDataSource() {    return new EmbeddedDataSource();  }
  • @Profile("prod") 对应 spring.profiles.active=prod

  • @Profile("dev | test") 对应 spring.profiles.active=dev 或 spring.profiles.active=test

它们根据配置文件中的 spring.profiles.active 属性值来决定激活哪个配置。

2.7 任务调度配置

@Configurationpublic class SchedulingConfig {  @Scheduled(cron = "${jobs.cleanup.schedule}")  public void databaseCleanup() {    // 清理逻辑  }  @Scheduled(fixedDelayString = "${jobs.health.interval}")  public void healthCheck() {    // 健康检查逻辑  }}

这两种方法都可以在不更改代码的情况下进行配置 完美地满足了在不同环境中需要不同时间的维护任务的要求。

2.8 @Scope作用域Bean

@Component@Scope(  value = WebApplicationContext.SCOPE_REQUEST  proxyMode = ScopedProxyMode.TARGET_CLASS)public class UserContext {  private User currentUser;  public void setCurrentUser(User user) {    this.currentUser = user;  }  public User getCurrentUser() {    return currentUser;  }}
  • 每个HTTP请求都会创建新实例

  • proxyMode可确保注入单例Bean时的正确作用域隔离

  • 非常适合在请求处理期间存储用户特定数据

  • 请求完成后自动清理

2.9 自动重试@Retryable

@Servicepublic class PaymentGatewayService {  @Retryable(    value = {TimeoutException.class},    maxAttempts = 3,    backoff = @Backoff(delay = 1000, multiplier = 2)  )  public PaymentResult processPayment(Payment payment) {    // TODO  }  @Recover  public PaymentResult handlePaymentFailure(TimeoutException e, Payment payment) {    return PaymentResult.failed(payment.getId());  }}
  • 自动重试请求超时异常

  • 尝试间隔采用指数退避策略(1秒、2秒、4秒)最多重试3次

  • @Recover方法提供回退逻辑

你需要引入如下依赖:

<dependency>  <groupId>org.springframework.retry</groupId>  <artifactId>spring-retry</artifactId></dependency>



以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

太强了!Spring Boot + JAXB 处理XML只需5行代码

Spring Boot + JavaScript 实时数据流:2种完整实现

告别OOM!Spring Boot 流式导出百万数据:支持MyBatis/JPA/Jdbc

高级开发!Spring Boot 零侵入读写分离:基于SQL解析全自动路由

SpringBoot+Nginx+Lua接口性能提升N倍

Tika 与 Spring Boot 的完美结合:支持任意文档解析的神器

Spring Boot中记录JDBC、JPA及MyBatis执行SQL及参数的正确姿势

优化!高并发下 Spring Boot 乐观锁 + 悲观锁性能调优

知道太晚了!实时通信新选择fetch-event-source,真香

告别内存溢出!Spring StreamingResponseBody 三大实战案例,性能提升100%

真香!RestTemplate、RestClient再不要直接使用了,新玩法来了

技术专家!Spring AOP + Nacos + Prometheus 实现动态限流及实时监控

图片
图片
图片
图片
图片
图片
图片
图片
图片

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读285
粉丝0
内容832