SpringBoot 中 10 个神器

向量数据库大模型数据库

在 Spring Boot 开发中,框架内置的诸多实用功能犹如一把把利刃,能让开发者在项目的各个阶段都事半功倍。这些功能无需额外集成,通过简单配置或编码即可快速实现常见需求。

下面将为你深入解析一系列极具价值的内置功能,帮助你更高效地构建应用。

picture.image点击这里获取:100万QPS短链系统、商城微服务、苏三AI项目、秒杀系统、商城系统、秒杀系统、代码生成工具等 7 个项目的 源代码、开发教程和技术答疑

一、请求数据全链路追踪:CommonsRequestLoggingFilter

在调试和监控阶段,记录请求的完整信息是定位问题的关键。Spring Boot 提供的 CommonsRequestLoggingFilter 可轻松实现请求数据的详细日志记录。

核心能力

多维度数据采集: 支持记录请求参数(includeQueryString)、请求体(includePayload)、请求头(includeHeaders)及客户端 IP 等信息。

灵活日志格式: 通过 setAfterMessagePrefix 自定义日志前缀,方便日志分类与检索。

快速启用
  • 配置过滤器:
  
@Configuration  
public class RequestLoggingConfig {  
    @Bean  
    public CommonsRequestLoggingFilter logFilter() {  
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();  
        filter.setIncludeQueryString(true); // 包含查询参数  
        filter.setIncludePayload(true);     // 包含请求体  
        filter.setMaxPayloadLength(1024);   // 限制请求体日志长度(避免大字段溢出)  
        filter.setAfterMessagePrefix("[REQUEST DATA] ");  
        return filter;  
    }  
}  

  • 设置日志级别:

application.properties 中开启 DEBUG 级日志:

  
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG  

日志示例
  
[REQUEST DATA] POST /api/user, client=192.168.1.1, headers=[Content-Type:application/json], payload={"username":"test","email":"test@example.com"}  

二、请求响应灵活操控:内容缓存包装器

原生 HttpServletRequestHttpServletResponse 的输入输出流仅支持单次读取,这在需要多次处理数据(如日志记录与业务逻辑分离)时存在局限。

Spring 提供的 ContentCachingRequestWrapperContentCachingResponseWrapper 完美解决了这一问题。

核心包装器

请求包装器(ContentCachingRequestWrapper) : 缓存请求体字节数据,允许多次读取。典型场景:记录请求日志后,控制器仍能正常解析请求体。

响应包装器(ContentCachingResponseWrapper) : 缓存响应输出流,支持在响应提交前修改内容(如添加签名、动态拼接数据)。

实战应用(过滤器实现)
  
// 请求包装器过滤器  
@Component  
publicclass RequestLogFilter extends OncePerRequestFilter {  
    @Override  
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
            throws ServletException, IOException {  
        // 包装请求,缓存输入流  
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);  
        byte[] requestBody = wrappedRequest.getContentAsByteArray();  
          
        // 记录请求日志(可在此处添加自定义逻辑)  
        log.debug("Received request body: {}", new String(requestBody));  
          
        // 传递包装后的请求,确保后续组件能重复读取  
        filterChain.doFilter(wrappedRequest, response);  
    }  
}  
  
// 响应包装器过滤器  
@Component  
publicclass ResponseSignFilter extends OncePerRequestFilter {  
    @Override  
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
            throws ServletException, IOException {  
        // 包装响应,缓存输出流  
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);  
          
        // 执行后续处理(控制器逻辑)  
        filterChain.doFilter(request, wrappedResponse);  
          
        // 响应后处理:添加签名  
        byte[] responseBody = wrappedResponse.getContentAsByteArray();  
        String signature = generateSignature(responseBody);  
        wrappedResponse.setHeader("X-Response-Signature", signature);  
          
        // 必须调用此方法将缓存内容写入原始响应  
        wrappedResponse.copyBodyToResponse();  
    }  
  
    private String generateSignature(byte[] body) {  
        // 自定义签名逻辑  
        return Base64.getEncoder().encodeToString(body);  
    }  
}  

三、单次执行保障:OncePerRequestFilter 基类

在请求转发(forward)或包含(include)场景中,普通过滤器可能重复执行,导致逻辑混乱。OncePerRequestFilter 确保过滤器在请求生命周期内仅执行一次,是处理状态性逻辑的理想选择。

核心优势

避免重复处理: 通过 shouldNotFilter 方法内部逻辑,自动识别同一请求的多次调度,确保 doFilterInternal 仅执行一次。

简化开发: 只需重写 doFilterInternal 方法,无需手动处理请求标识或缓存执行状态。

适用场景

日志记录: 避免转发时重复打印日志。

安全校验: 如 JWT 解析,确保身份验证仅执行一次。

性能监控: 精确记录单次请求处理耗时,避免统计误差。

四、AOP 开发助力:实用工具类三件套

Spring AOP 的强大离不开三个辅助类,它们简化了代理对象操作与反射逻辑,是切面编程的得力助手。

1. AopContext:代理对象访问器

当同一类中方法调用导致注解(如 @Transactional)失效时,AopContext.currentProxy() 可获取当前代理对象,确保切面逻辑正确触发:

  
public class ServiceImpl {  
    @Transactional  
    public void innerMethod() {  
        // 正常事务逻辑  
    }  
  
    public void outerMethod() {  
        // 直接调用 innerMethod 会跳过代理,导致事务失效  
        // 正确方式:通过代理对象调用  
        ((ServiceImpl) AopContext.currentProxy()).innerMethod();  
    }  
}  

2. AopUtils:代理类型判断工具

提供静态方法快速识别代理类型,便于动态处理不同代理逻辑:

  
if (AopUtils.isJdkDynamicProxy(proxyObject)) {  
    // 处理 JDK 动态代理  
} elseif (AopUtils.isCglibProxy(proxyObject)) {  
    // 处理 CGLIB 代理  
}  

3. ReflectionUtils:反射操作简化器

封装繁琐的反射 API,支持安全访问私有成员:

  
// 访问私有字段  
Field field = ReflectionUtils.findField(MyClass.class, "privateField");  
ReflectionUtils.makeAccessible(field);  
Object value = ReflectionUtils.getField(field, objectInstance);  
  
// 调用私有方法  
Method method = ReflectionUtils.findMethod(MyClass.class, "privateMethod", String.class);  
ReflectionUtils.invokeMethod(method, objectInstance, "参数");  

五、依赖管理魔法:Starter 自动装配体系

Spring Boot 最显著的生产力提升工具之一是 Starter 依赖体系,通过命名规范清晰的 “一站式” 依赖包,开发者无需手动搜索和匹配兼容版本,框架自动处理传递依赖冲突。

核心优势

极简依赖声明: 例如添加 Web 开发依赖只需引入 spring-boot-starter-web,框架自动包含 Tomcat、Spring MVC、Jackson 等必需库。

版本统一管理: 通过 spring-boot-dependencies 父 POM 锁定所有依赖的兼容版本,避免版本冲突。

常用 Starter 示例

picture.image

自定义 Starter

若需封装内部通用功能,可创建自定义 Starter:

src/main/resources/META-INF 下添加 spring.factories

  
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  
com.example.custom.MyCustomAutoConfiguration  

编写自动配置类,利用 @ConditionalOnClass@ConditionalOnMissingBean 等条件注解实现智能装配。

六、配置简化利器:自动配置与灵活占位符

Spring Boot 通过 自动配置(Auto Configuration) 和 配置属性绑定(@ConfigurationProperties) 大幅减少样板代码,支持从 application.properties/yml 中动态注入配置。

1. 智能自动配置

框架通过 @EnableAutoConfiguration 扫描类路径,根据依赖自动配置 Bean。例如:

引入 spring-boot-starter-jdbc 后,自动配置 DataSourceJdbcTemplate

检测到 spring-data-mongodb,自动配置 MongoDB 相关连接和操作组件。

2. 类型安全的配置绑定

通过 @ConfigurationProperties 将配置文件映射到 POJO,避免硬编码:

  
@Configuration  
@ConfigurationProperties(prefix = "app")  
publicclass AppConfig {  
    private String env;  
    private DatabaseConfig database;  
  
    // getter/setter  
    publicstaticclass DatabaseConfig {  
        private String url;  
        private String username;  
        // ...  
    }  
}  

application.yml 配置:

  
app:  
  env: production  
  database:  
    url: jdbc:mysql://localhost:3306/test  
    username: root  

3. 灵活占位符

支持在配置中使用 ${} 引用其他配置或系统变量,结合 @Value 注入:

  
@Value("${app.env:dev}") // 默认值处理  
private String environment;  

七、异步与定时任务:注解驱动的并发处理

Spring Boot 通过 @Async@Scheduled 注解简化异步任务和定时任务开发,无需手动编写线程池或 Quartz 配置。

1. 异步方法调用

标注 @Async 的方法会在独立线程中执行,配合 @EnableAsync 启用:

  
@Service  
publicclass AsyncService {  
    @Async("customExecutor") // 指定线程池  
    public CompletableFuture<Void> processAsyncTask(String taskId) {  
        // 耗时操作  
        return CompletableFuture.completedFuture(null);  
    }  
}  
  
// 配置自定义线程池  
@Configuration  
@EnableAsync  
publicclass AsyncConfig {  
    @Bean("customExecutor")  
    public Executor asyncExecutor() {  
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  
        executor.setCorePoolSize(5);  
        executor.setMaxPoolSize(10);  
        executor.setQueueCapacity(20);  
        executor.initialize();  
        return executor;  
    }  
}  

2. 定时任务调度

使用 @Scheduled 定义周期性任务,支持 Cron 表达式或固定间隔:

  
@Service  
public class ScheduledService {  
    // 每天凌晨 1 点执行  
    @Scheduled(cron = "0 0 1 * * ?")   
    public void dailyCleanup() {  
        // 数据清理逻辑  
    }  
  
    // 每隔 5 秒执行(上一次完成后等待)  
    @Scheduled(fixedDelay = 5000)   
    public void periodicSync() {  
        // 同步任务  
    }  
}  

八、监控与诊断:Actuator 生产级工具

Spring Boot Actuator 提供开箱即用的端点(Endpoint),帮助开发者监控应用状态、查看性能指标,甚至动态调整配置。

核心端点

picture.image

自定义指标

通过 MeterRegistry 添加业务指标:

  
@Autowired  
private MeterRegistry meterRegistry;  
  
public void recordOrder(String status) {  
    meterRegistry.counter("order.processed", "status", status).increment();  
}  

九、表达式的力量:SpEL 动态计算能力

Spring 表达式语言(SpEL)允许在配置、注解甚至代码中动态求值,实现灵活的逻辑控制。

典型应用场景

Bean 定义中的表达式:

  
<bean id="userService" class="com.example.UserService">  
    <property name="defaultTimeout" value="#{T(java.lang.Integer).parseInt('1000')}"/>  
</bean>  

条件注解中的逻辑:

  
@ConditionalOnExpression("${app.env} == 'prod' && @environment.getProperty('server.port') == 8080")  
public class ProdConfig {  
    // 生产环境专属配置  
}  

安全表达式(Spring Security) :

  
@PreAuthorize("hasRole('ADMIN') or @accessService.hasPermission(#userId)")  
public void deleteUser(Long userId) {  
    // 权限控制逻辑  
}  

总结

Spring Boot 的这些内置功能覆盖了从开发到运维的全链路流程,合理运用这些工具,既能减少重复代码,又能提升系统的可维护性与健壮性。建议开发者在实际项目中根据需求灵活组合,充分发挥框架的原生优势。

原文:juejin.cn/post/7499508081651695667

最后欢迎加入苏三的星球,你将获得:100万QPS短链系统、复杂的商城微服务系统、苏三AI项目、刷题吧小程序、秒杀系统、商城系统、秒杀系统、代码生成工具等8个项目的源代码、开发教程和技术答疑。

系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1免费修改简历、技术答疑、职业规划、送书活动、技术交流。

目前星球已经更新了5800+篇优质内容,还在持续爆肝中.....

扫描下方二维码即可加入星球:

picture.image

现在加入是非常合适的,本月底要正式涨价了。

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有1800+小伙伴加入学习。

picture.image 你在看吗

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生机器学习系统落地和实践
机器学习在字节跳动有着丰富业务场景:推广搜、CV/NLP/Speech 等。业务规模的不断增大对机器学习系统从用户体验、训练效率、编排调度、资源利用等方面也提出了新的挑战,而 Kubernetes 云原生理念的提出正是为了应对这些挑战。本次分享将主要介绍字节跳动机器学习系统云原生化的落地和实践。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论