10個SpringBoot框架內(nèi)置的實(shí)用功能詳解
一、請求數(shù)據(jù)全鏈路追蹤:CommonsRequestLoggingFilter
在調(diào)試和監(jiān)控階段,記錄請求的完整信息是定位問題的關(guān)鍵。Spring Boot 提供的 CommonsRequestLoggingFilter 可輕松實(shí)現(xiàn)請求數(shù)據(jù)的詳細(xì)日志記錄。
核心能力
多維度數(shù)據(jù)采集: 支持記錄請求參數(shù)(includeQueryString)、請求體(includePayload)、請求頭(includeHeaders)及客戶端 IP 等信息。
靈活日志格式: 通過 setAfterMessagePrefix 自定義日志前綴,方便日志分類與檢索。
快速啟用
- 配置過濾器:
@Configuration
public class RequestLoggingConfig {
@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true); // 包含查詢參數(shù)
filter.setIncludePayload(true); // 包含請求體
filter.setMaxPayloadLength(1024); // 限制請求體日志長度(避免大字段溢出)
filter.setAfterMessagePrefix("[REQUEST DATA] ");
return filter;
}
}
- 設(shè)置日志級別:
在 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"}二、請求響應(yīng)靈活操控:內(nèi)容緩存包裝器
原生 HttpServletRequest 和 HttpServletResponse 的輸入輸出流僅支持單次讀取,這在需要多次處理數(shù)據(jù)(如日志記錄與業(yè)務(wù)邏輯分離)時存在局限。
Spring 提供的 ContentCachingRequestWrapper 和 ContentCachingResponseWrapper 完美解決了這一問題。
核心包裝器
請求包裝器(ContentCachingRequestWrapper) : 緩存請求體字節(jié)數(shù)據(jù),允許多次讀取。典型場景:記錄請求日志后,控制器仍能正常解析請求體。
響應(yīng)包裝器(ContentCachingResponseWrapper) : 緩存響應(yīng)輸出流,支持在響應(yīng)提交前修改內(nèi)容(如添加簽名、動態(tài)拼接數(shù)據(jù))。
實(shí)戰(zhàn)應(yīng)用(過濾器實(shí)現(xiàn))
// 請求包裝器過濾器
@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));
// 傳遞包裝后的請求,確保后續(xù)組件能重復(fù)讀取
filterChain.doFilter(wrappedRequest, response);
}
}
// 響應(yīng)包裝器過濾器
@Component
publicclass ResponseSignFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 包裝響應(yīng),緩存輸出流
ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
// 執(zhí)行后續(xù)處理(控制器邏輯)
filterChain.doFilter(request, wrappedResponse);
// 響應(yīng)后處理:添加簽名
byte[] responseBody = wrappedResponse.getContentAsByteArray();
String signature = generateSignature(responseBody);
wrappedResponse.setHeader("X-Response-Signature", signature);
// 必須調(diào)用此方法將緩存內(nèi)容寫入原始響應(yīng)
wrappedResponse.copyBodyToResponse();
}
private String generateSignature(byte[] body) {
// 自定義簽名邏輯
return Base64.getEncoder().encodeToString(body);
}
}
三、單次執(zhí)行保障:OncePerRequestFilter 基類
在請求轉(zhuǎn)發(fā)(forward)或包含(include)場景中,普通過濾器可能重復(fù)執(zhí)行,導(dǎo)致邏輯混亂。OncePerRequestFilter 確保過濾器在請求生命周期內(nèi)僅執(zhí)行一次,是處理狀態(tài)性邏輯的理想選擇。
核心優(yōu)勢
避免重復(fù)處理: 通過 shouldNotFilter 方法內(nèi)部邏輯,自動識別同一請求的多次調(diào)度,確保 doFilterInternal 僅執(zhí)行一次。
簡化開發(fā): 只需重寫 doFilterInternal 方法,無需手動處理請求標(biāo)識或緩存執(zhí)行狀態(tài)。
適用場景
日志記錄: 避免轉(zhuǎn)發(fā)時重復(fù)打印日志。
安全校驗: 如 JWT 解析,確保身份驗證僅執(zhí)行一次。
性能監(jiān)控: 精確記錄單次請求處理耗時,避免統(tǒng)計誤差。
四、AOP 開發(fā)助力:實(shí)用工具類三件套
Spring AOP 的強(qiáng)大離不開三個輔助類,它們簡化了代理對象操作與反射邏輯,是切面編程的得力助手。
1. AopContext:代理對象訪問器
當(dāng)同一類中方法調(diào)用導(dǎo)致注解(如 @Transactional)失效時,AopContext.currentProxy() 可獲取當(dāng)前代理對象,確保切面邏輯正確觸發(fā):
public class ServiceImpl {
@Transactional
public void innerMethod() {
// 正常事務(wù)邏輯
}
public void outerMethod() {
// 直接調(diào)用 innerMethod 會跳過代理,導(dǎo)致事務(wù)失效
// 正確方式:通過代理對象調(diào)用
((ServiceImpl) AopContext.currentProxy()).innerMethod();
}
}
2. AopUtils:代理類型判斷工具
提供靜態(tài)方法快速識別代理類型,便于動態(tài)處理不同代理邏輯:
if (AopUtils.isJdkDynamicProxy(proxyObject)) {
// 處理 JDK 動態(tài)代理
} else if (AopUtils.isCglibProxy(proxyObject)) {
// 處理 CGLIB 代理
}
3. ReflectionUtils:反射操作簡化器
封裝繁瑣的反射 API,支持安全訪問私有成員:
// 訪問私有字段 Field field = ReflectionUtils.findField(MyClass.class, "privateField"); ReflectionUtils.makeAccessible(field); Object value = ReflectionUtils.getField(field, objectInstance); // 調(diào)用私有方法 Method method = ReflectionUtils.findMethod(MyClass.class, "privateMethod", String.class); ReflectionUtils.invokeMethod(method, objectInstance, "參數(shù)");
五、依賴管理魔法:Starter 自動裝配體系
Spring Boot 最顯著的生產(chǎn)力提升工具之一是 Starter 依賴體系,通過命名規(guī)范清晰的 “一站式” 依賴包,開發(fā)者無需手動搜索和匹配兼容版本,框架自動處理傳遞依賴沖突。
核心優(yōu)勢
極簡依賴聲明: 例如添加 Web 開發(fā)依賴只需引入 spring-boot-starter-web,框架自動包含 Tomcat、Spring MVC、Jackson 等必需庫。
版本統(tǒng)一管理: 通過 spring-boot-dependencies 父 POM 鎖定所有依賴的兼容版本,避免版本沖突。
常用 Starter 示例

自定義 Starter
若需封裝內(nèi)部通用功能,可創(chuàng)建自定義 Starter:
在 src/main/resources/META-INF 下添加 spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.custom.MyCustomAutoConfiguration
編寫自動配置類,利用 @ConditionalOnClass、@ConditionalOnMissingBean 等條件注解實(shí)現(xiàn)智能裝配。
六、配置簡化利器:自動配置與靈活占位符
Spring Boot 通過 自動配置(Auto Configuration) 和 配置屬性綁定(@ConfigurationProperties) 大幅減少樣板代碼,支持從 application.properties/yml 中動態(tài)注入配置。
1. 智能自動配置
框架通過 @EnableAutoConfiguration 掃描類路徑,根據(jù)依賴自動配置 Bean。例如:
引入 spring-boot-starter-jdbc 后,自動配置 DataSource、JdbcTemplate。
檢測到 spring-data-mongodb,自動配置 MongoDB 相關(guān)連接和操作組件。
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. 靈活占位符
支持在配置中使用 ${} 引用其他配置或系統(tǒng)變量,結(jié)合 @Value 注入:
@Value("${app.env:dev}") // 默認(rèn)值處理
private String environment;
七、異步與定時任務(wù):注解驅(qū)動的并發(fā)處理
Spring Boot 通過 @Async 和 @Scheduled 注解簡化異步任務(wù)和定時任務(wù)開發(fā),無需手動編寫線程池或 Quartz 配置。
1. 異步方法調(diào)用
標(biāo)注 @Async 的方法會在獨(dú)立線程中執(zhí)行,配合 @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. 定時任務(wù)調(diào)度
使用 @Scheduled 定義周期性任務(wù),支持 Cron 表達(dá)式或固定間隔:
@Service
public class ScheduledService {
// 每天凌晨 1 點(diǎn)執(zhí)行
@Scheduled(cron = "0 0 1 * * ?")
public void dailyCleanup() {
// 數(shù)據(jù)清理邏輯
}
// 每隔 5 秒執(zhí)行(上一次完成后等待)
@Scheduled(fixedDelay = 5000)
public void periodicSync() {
// 同步任務(wù)
}
}
八、監(jiān)控與診斷:Actuator 生產(chǎn)級工具
Spring Boot Actuator 提供開箱即用的端點(diǎn)(Endpoint),幫助開發(fā)者監(jiān)控應(yīng)用狀態(tài)、查看性能指標(biāo),甚至動態(tài)調(diào)整配置。
核心端點(diǎn)

自定義指標(biāo)
通過 MeterRegistry 添加業(yè)務(wù)指標(biāo):
@Autowired
private MeterRegistry meterRegistry;
public void recordOrder(String status) {
meterRegistry.counter("order.processed", "status", status).increment();
}
九、表達(dá)式的力量:SpEL 動態(tài)計算能力
Spring 表達(dá)式語言(SpEL)允許在配置、注解甚至代碼中動態(tài)求值,實(shí)現(xiàn)靈活的邏輯控制。
典型應(yīng)用場景
Bean 定義中的表達(dá)式:
<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 {
// 生產(chǎn)環(huán)境專屬配置
}
安全表達(dá)式(Spring Security) :
@PreAuthorize("hasRole('ADMIN') or @accessService.hasPermission(#userId)")
public void deleteUser(Long userId) {
// 權(quán)限控制邏輯
}
總結(jié)
Spring Boot 的這些內(nèi)置功能覆蓋了從開發(fā)到運(yùn)維的全鏈路流程,合理運(yùn)用這些工具,既能減少重復(fù)代碼,又能提升系統(tǒng)的可維護(hù)性與健壯性。建議開發(fā)者在實(shí)際項目中根據(jù)需求靈活組合,充分發(fā)揮框架的原生優(yōu)勢。
以上就是10個SpringBoot框架內(nèi)置的實(shí)用功能詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot框架內(nèi)置功能的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot配置log4j2的實(shí)現(xiàn)示例
SpringBoot中默認(rèn)使用Logback作為日志框架,本文主要介紹了SpringBoot配置log4j2的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-12-12
解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請求數(shù)據(jù)丟失問題
這篇文章主要介紹了解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請求數(shù)據(jù)丟失問題,主要包括無異步線程得情況下feign遠(yuǎn)程調(diào)用,異步情況下丟失上下文問題,需要的朋友可以參考下2022-05-05
springboot 自定義配置Boolean屬性不生效的解決
這篇文章主要介紹了springboot 自定義配置Boolean屬性不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
java-流的使用完結(jié)與異常處理機(jī)制(詳解)
下面小編就為大家?guī)硪黄猨ava-流的使用完結(jié)與異常處理機(jī)制(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
java獲取鍵盤輸入的數(shù)字,并進(jìn)行排序的方法
今天小編就為大家分享一篇java獲取鍵盤輸入的數(shù)字,并進(jìn)行排序的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07

