zhaosf做這樣網(wǎng)站百度指數(shù)查詢
摘要: 本文將介紹如何創(chuàng)建一個自定義的 Spring Boot Starter,讓您可以封裝常用功能和配置,并在多個 Spring Boot 項目中共享和重用。
1. 簡介
Spring Boot Starter 是 Spring Boot 框架中的一種特殊的依賴項,它用于快速啟動和配置特定功能的應(yīng)用程序。Starter 實際上是一個 Maven 或 Gradle 項目,它包含了一組預(yù)配置的依賴項、默認(rèn)的配置信息和自動配置類,以幫助開發(fā)者快速集成和使用某項功能。
Spring Boot Starter 通常命名為 spring-boot-starter-*
,例如 spring-boot-starter-web
用于啟動基本的Web應(yīng)用程序,spring-boot-starter-data-jpa
用于啟動使用JPA的數(shù)據(jù)訪問應(yīng)用程序。
2.背景
在企業(yè)微服務(wù)開發(fā)中,每個微服務(wù)模塊可能會有不同的異常處理和錯誤信息輸出方式,這樣會導(dǎo)致系統(tǒng)的一致性和可維護性下降。為了解決這個問題,您希望創(chuàng)建一個自定義的 Spring Boot Starter,用于統(tǒng)一處理異常和錯誤信息,并提供一致的錯誤響應(yīng)格式。
3.需求
-
統(tǒng)一的異常處理:對于常見的異常類型(如 404、500),提供統(tǒng)一的異常處理方式,并返回一致的錯誤響應(yīng)。
-
統(tǒng)一的錯誤響應(yīng)格式:定義一致的錯誤響應(yīng)格式,包括錯誤代碼、錯誤消息、錯誤詳情等信息。
-
可定制化:允許開發(fā)人員根據(jù)實際情況定制異常處理和錯誤響應(yīng)的方式,以滿足不同的業(yè)務(wù)需求。
4.實現(xiàn)
4.1.創(chuàng)建SpringBoot項目
創(chuàng)建完成后項目結(jié)構(gòu)
4.2.添加相關(guān)依賴
這里需要注意的是,在build.gradle文件中,我們在這里引入了? id 'java-library'
plugins {id 'java'// 添加 maven-publish 插件 主要是為了發(fā)布項目到 Maven 倉庫id 'maven-publish'// 應(yīng)用 Java Library 插件,提供 Java 項目的基本構(gòu)建功能id 'java-library'}group = 'org.sys_my_start'
version = '1.0-SNAPSHOT'
ext {springfoxVersion = '3.2.2'
}// 配置發(fā)布任務(wù)
publishing {// 定義發(fā)布內(nèi)容publications {// 定義一個 MavenPublication 類型的發(fā)布mavenJava(MavenPublication) {// 發(fā)布內(nèi)容來源于 Java 組件from components.java// 定義 Maven 坐標(biāo)信息groupId 'org.sys_my_start' // Maven 項目的組織或公司標(biāo)識artifactId 'com_sys_my_start' // 項目在 Maven 倉庫中的唯一標(biāo)識version '1.0-SNAPSHOT' // 項目的版本號,表示開發(fā)中的版本}}
}repositories {mavenCentral()
}/* api: 這個依賴聲明范圍表示該依賴項不僅僅對當(dāng)前項目的編譯和運行時可見,而且對于其他依賴于當(dāng)前項目的項目也是可見的。換句話說,當(dāng)一個項目依賴于當(dāng)前項目時,它也將自動獲得該依賴項。(也就是最外層的可以訪問最內(nèi)層所引入的依賴)上面引入這個 也是為了使用api 因為 gradle 7.0 以后默認(rèn)不支持 compile語法了廢棄了,所以我們這里需要使用apiid 'java-library'
*/
dependencies {api "org.springframework.boot:spring-boot-starter-web:$springfoxVersion"
}test {useJUnitPlatform()
}
4.3.編寫Starter 主要邏輯
4.3.1.編寫異常處理類
package com.sys.my.start.exception;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;@ControllerAdvice
public class GlobalExceptionHandler {private final ExceptionHandlerProperties properties;@Autowiredpublic GlobalExceptionHandler(ExceptionHandlerProperties properties) {this.properties = properties;}/*** 處理自定義異常* @param ex 自定義異常* @param request 請求* @return ResponseEntity 返回異常信息*/@ExceptionHandler(Exception.class)public ResponseEntity<ErrorResponse> handleAnyException(Exception ex, WebRequest request) {if (properties.isEnabled()) {// 處理自定義異常, 返回異常信息ErrorResponse errorResponse = new ErrorResponse("500", ex.getMessage(), request.getDescription(false));return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);} else {// 未啟用全局異常處理 返回500return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);}}
}
4.3.2.編寫錯誤響應(yīng)類
package com.sys.my.start.exception;/*** 定義統(tǒng)一錯誤相應(yīng)格式*/
public class ErrorResponse {/*** 錯誤碼*/private String errorCode;/*** 錯誤信息*/private String errorMessage;/*** 錯誤詳情*/private String errorDetails;public ErrorResponse(String number, String message, String description) {this.errorCode = number;this.errorMessage = message;this.errorDetails = description;}public String getErrorCode() {return errorCode;}public String getErrorMessage() {return errorMessage;}public String getErrorDetails() {return errorDetails;}public void setErrorCode(String errorCode) {this.errorCode = errorCode;}public void setErrorMessage(String errorMessage) {this.errorMessage = errorMessage;}public void setErrorDetails(String errorDetails) {this.errorDetails = errorDetails;}
}
4.3.3.編寫掃描配置文件類
package com.sys.my.start.exception;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 掃描 exception-handler:* enabled: true* 為true時,啟用全局異常處理*/
@Component
@ConfigurationProperties(prefix = "exception-handler")
public class ExceptionHandlerProperties {private boolean enabled;public boolean isEnabled() {return enabled;}public void setEnabled(boolean enabled) {this.enabled = enabled;}
}
4.3.4.編寫自動配置類
package com.sys.my.start.exception;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;import java.lang.invoke.MethodHandles;/*** 自動配置類* 通過@Import導(dǎo)入相關(guān)文件* EnableAspectJAutoProxy開啟AOP代理自動配置* @author 13723* @version 1.0* 2024/2/16 19:16*/
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true
)
@Import({ExceptionHandlerProperties.class})
public class ErrorHandlerAutoProxy {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
}
4.3.5.編寫spring.factories
# 通過SpringBoot的自動注入功能,掃描spring.factories,實現(xiàn)自動注入。
org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.sys.my.start.exception.ErrorHandlerAutoProxy
4.3.6.發(fā)布到本地gradle
5.測試
5.1.測試模塊引入starter
注意 這里為了保證測試的service模塊能夠使用到 starter引入springboot依賴,也需要使用api進行調(diào)用
// sys_my_service 子項目中的 build.gradle
plugins {id 'java-library'
}
dependencies {// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2/* json轉(zhuǎn)換 */implementation 'com.alibaba.fastjson2:fastjson2:2.0.46'/* lombok */compileOnly 'org.projectlombok:lombok'annotationProcessor 'org.projectlombok:lombok'/* 日志類 */api 'ch.qos.logback:logback-classic:1.4.14'/* 引入自定義jar包 */api group: 'org.sys_my_start', name: 'com_sys_my_start', version: '1.0-SNAPSHOT'
}
sourceSets.main.resources {srcDirs = ['src/main/java']include '**/*.xml'
}
5.2.編寫測試代碼
/*** @author 13723* @version 1.0* 2024/2/16 13:32*/
@RestController
@RequestMapping("/test")
public class TestController {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());@Resourceprivate TestService testService;@RequestMapping("/hello")public String hello(){return testService.hello();}
}
/*** @author 13723* @version 1.0* 2024/2/16 13:33*/@Service
public class TestService {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public String hello(){throw new RuntimeException("測試統(tǒng)一返回異常!");}
}
5.3.測試結(jié)果
6.總結(jié)
6.1.好處
自定義 Starter 是在 Spring Boot 中實現(xiàn)代碼模塊化和功能封裝的強大工具。它的優(yōu)勢和用途包括:
- 模塊化開發(fā): 自定義 Starter 允許將應(yīng)用程序的不同功能模塊化,使得代碼結(jié)構(gòu)更清晰,易于維護和管理。
- 功能封裝: Starter 可以封裝特定功能的代碼和配置,使得其他開發(fā)人員可以輕松地集成和使用這些功能。
- 提高開發(fā)效率: 使用自定義 Starter 可以加速新項目的開發(fā)過程,避免重復(fù)編寫相似的代碼,提高開發(fā)效率。
- 標(biāo)準(zhǔn)化配置: Starter 可以定義標(biāo)準(zhǔn)化的配置方式,使得不同項目之間的配置更一致,降低了配置錯誤的可能性。
通過自定義 Starter,開發(fā)團隊可以實現(xiàn)代碼的復(fù)用和標(biāo)準(zhǔn)化,從而提高了代碼的復(fù)用性和可維護性,降低了開發(fā)和維護成本。
6.2.結(jié)語
本文介紹了如何創(chuàng)建自定義的 Spring Boot Starter,并詳細(xì)解釋了其優(yōu)勢、用途以及如何提高代碼復(fù)用性和可維護性。通過自定義 Starter,開發(fā)人員可以更輕松地構(gòu)建模塊化的應(yīng)用程序,并在團隊內(nèi)部實現(xiàn)功能的共享和復(fù)用。
鼓勵讀者在實際項目中嘗試創(chuàng)建自己的自定義 Starter,將通用的功能模塊化,并通過開源社區(qū)與他人分享,促進技術(shù)的共享和交流。這將有助于提高團隊的開發(fā)效率,加速項目的上線和迭代過程,推動軟件開發(fā)行業(yè)的發(fā)展。