別再重復(fù)造輪子!SpringBoot 內(nèi)置的 20個(gè)高效工具類(lèi)
SpringBoot 內(nèi)置的 20 個(gè)高效工具類(lèi)
還在自己寫(xiě)工具類(lèi)?你已經(jīng)被SpringBoot拋棄了!很多人嘴上說(shuō)“別重復(fù)造輪子”,結(jié)果還在項(xiàng)目里一遍遍寫(xiě)String工具、Bean拷貝、文件處理、反射操作……
SpringBoot 內(nèi)置了 20個(gè)寶藏工具類(lèi),輕量級(jí)、性能強(qiáng)、低耦合,很多大廠架構(gòu)師都在用,可你可能連名字都沒(méi)聽(tīng)過(guò)!
有人說(shuō):“用這些就像開(kāi)了外掛?!币灿腥苏f(shuō):“太黑箱,寧愿自己寫(xiě)。”你怎么看?
一、數(shù)據(jù)處理
1. StringUtils
Spring 提供的 StringUtils
相比 Apache Commons Lang 版本更加輕量,且與 Spring 生態(tài)完美集成。它提供了字符串判空、截取、拼接等常用操作,比如:
// 判斷字符串是否為空 StringUtils.isEmpty(str); // 判斷字符串是否有內(nèi)容 StringUtils.hasText(str); // 數(shù)組合并成字符串 StringUtils.arrayToCommaDelimitedString(arr);
2. ObjectUtils
處理對(duì)象判空和默認(rèn)值時(shí),不要再寫(xiě) if-else 了:
// 安全判空 ObjectUtils.isEmpty(obj); // 獲取第一個(gè)非空對(duì)象 ObjectUtils.firstNonNull(obj1, obj2, defaultValue); // 空安全toString ObjectUtils.nullSafeToString(obj);
3. CollectionUtils
Spring 的集合工具類(lèi)讓集合操作更加優(yōu)雅:
// 集合判空 CollectionUtils.isEmpty(collection); // 查找第一個(gè)匹配元素 CollectionUtils.find(collection, predicate); // 合并數(shù)組 CollectionUtils.mergeArrayIntoCollection(arr, collection);
二、HTTP 請(qǐng)求
1. RestTemplate
傳統(tǒng)同步請(qǐng)求
雖然已被標(biāo)記為過(guò)時(shí),但在非響應(yīng)式項(xiàng)目中依然實(shí)用:
// 簡(jiǎn)單GET請(qǐng)求 String result = restTemplate.getForObject(url, String.class); // 帶參數(shù)的POST請(qǐng)求 ResponseEntity<String> response = restTemplate.postForEntity( url, request, String.class);
2. WebClient
Spring 5 引入的響應(yīng)式 HTTP 客戶端:
WebClient.create() .get() .uri(url) .retrieve() .bodyToMono(String.class) .subscribe(result -> System.out.println(result));
3. TestTemplate
專(zhuān)門(mén)為測(cè)試設(shè)計(jì)的增強(qiáng)版 RestTemplate:
@Test public void testApi() { ResponseEntity<String> response = testRestTemplate .getForEntity("/api/test", String.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); }
4. MockRestServiceServer
測(cè)試時(shí)模擬外部 API 調(diào)用:
MockRestServiceServer server = MockRestServiceServer .bindTo(restTemplate).build(); server.expect(requestTo("/external/api")) .andRespond(withSuccess("mock response", MediaType.APPLICATION_JSON));
三、緩存 & 異步
1. CacheManager
Spring 的緩存抽象層支持多種實(shí)現(xiàn):
@Cacheable(value = "users", key = "#id") public User getUser(Long id) { // 數(shù)據(jù)庫(kù)查詢 } @CacheEvict(value = "users", key = "#id") public void updateUser(User user) { // 更新邏輯 }
2. @Async + TaskExecutor
輕松實(shí)現(xiàn)方法異步執(zhí)行:
@Async public CompletableFuture<User> asyncGetUser(Long id) { // 耗時(shí)操作 return CompletableFuture.completedFuture(user); } // 配置線程池 @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); return executor; }
3. EventPublishe
實(shí)現(xiàn)應(yīng)用內(nèi)事件發(fā)布訂閱:
// 定義事件 public class UserRegisteredEvent extends ApplicationEvent { public UserRegisteredEvent(User user) { super(user); } } // 發(fā)布事件 applicationEventPublisher.publishEvent(new UserRegisteredEvent(user)); // 監(jiān)聽(tīng)事件 @EventListener public void handleEvent(UserRegisteredEvent event) { // 處理邏輯 }
四、校驗(yàn) & 日志
1. Assert
Spring 的斷言工具讓參數(shù)檢查更簡(jiǎn)潔:
// 參數(shù)校驗(yàn) Assert.notNull(param, "參數(shù)不能為空"); Assert.isTrue(value > 0, "值必須大于0"); // 狀態(tài)檢查 Assert.state(isValid, "狀態(tài)不合法");
2. @Validated + BindingResult
結(jié)合 JSR-303 實(shí)現(xiàn)參數(shù)校驗(yàn):
@PostMapping("/users") public ResponseEntity createUser( @Validated @RequestBody User user, BindingResult result) { if (result.hasErrors()) { // 處理校驗(yàn)錯(cuò)誤 } // 業(yè)務(wù)邏輯 }
3. Logback
/Log4j2
SpringBoot 自動(dòng)配置的日志系統(tǒng):
# application.properties logging.level.root=INFO logging.level.com.example=DEBUG logging.file.name=app.log logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
五、測(cè)試 & 調(diào)試
1. MockMvc
測(cè)試 Controller 層的利器:
@SpringBootTest @AutoConfigureMockMvc class UserControllerTest { @Autowired private MockMvc mockMvc; @Test void testGetUser() throws Exception { mockMvc.perform(get("/users/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("張三")); } }
2. OutputCapture
捕獲并驗(yàn)證日志輸出:
@SpringBootTest class LoggingTest { @Autowired private MyService service; @Rule public OutputCapture outputCapture = new OutputCapture(); @Test void testLogging() { service.doSomething(); assertThat(outputCapture.toString()) .contains("操作已完成"); } }
3. TestPropertyValues
靈活修改測(cè)試環(huán)境配置:
@Test void testWithDynamicProperties() { TestPropertyValues.of( "app.timeout=5000", "app.enabled=true" ).applyTo(environment); // 執(zhí)行測(cè)試 }
4. SpringBootTest
完整的集成測(cè)試支持:
@SpringBootTest( webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"app.env=test"} ) class FullIntegrationTest { @LocalServerPort private int port; @Test void testFullStack() { // 測(cè)試完整應(yīng)用棧 } }
六、冷門(mén)但實(shí)用的工具
1. BannerCustomizer
讓?xiě)?yīng)用啟動(dòng)更有個(gè)性:
@Bean public BannerCustomizer myBannerCustomizer() { return banner -> { banner.setBanner(new ResourceBanner( new ClassPathResource("banner.txt"))); banner.setMode(Banner.Mode.LOG); }; }
2. Environment
靈活訪問(wèn)環(huán)境變量和配置:
@Autowired private Environment env; public void someMethod() { String dbUrl = env.getProperty("spring.datasource.url"); boolean debug = env.getProperty("app.debug", Boolean.class, false); }
3. SpelExpressionParser
運(yùn)行時(shí)執(zhí)行 SpEL 表達(dá)式:
ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("name.toUpperCase()"); String result = exp.getValue(userContext, String.class);#SpringBoot#