親愛的 JAVAer 們,在平時編碼的過程中,你是否曾想過編寫一個 Java 框架去為開發提效?但是要么編寫框架時感覺無從下手,不知道從哪開始。要么有思路了后對某個功能實現的技術細節不了解,空有想法而無法實現。如果你遇到了這些問題,看完這篇文章你也能用 ChatGPT 編寫一個簡單的 JAVA 框架。
構思清晰
首先,你需要明確你的框架要解決什么問題,具有什么特性。這將有助于 ChatGPT 更好的理解你的需求。
例如:我在一個前后端分離的需求中發現有太多的枚舉類的描述需要給前端返回。傳統的方式是后端根據枚舉類的映射,每個枚舉值編寫代碼映射成描述給前端返回。但這次需求需要給前端返回的枚舉描述太多了。這讓我和我的小伙伴們感覺無從下手。所以我就思考能否編寫一個注解自動幫我們掃描這些枚舉類,然后生成 key 和描述的 map,最終放到容器中去呢?
解決問題:解決前后端分離過程中需要手動編寫代碼將枚舉 key 的描述映射給前端。
特性:框架有一個注解,注解有三個字段 name,key,和 desc,修飾在枚舉類上。框架需提供外部獲取枚舉 map 的接口。
與 ChatGPT 交流
啟動 ChatGPT,向它講述你的構想和需求。它可以為你生成初始代碼、提供結構建議,甚至幫你處理一些邏輯。
想好了框架要解決的問題和框架的特性之后,接下來就要將框架要解決的問題和特性給總結成一段文字發給 ChatGPT
??chatgpt 根據我的需求大概生成了下框架的 demo 版本。可以看到和我設想的還是有些區別的,我想是將枚舉放在類上。然后枚舉的屬性有 name,key,和 desc。
name:代表枚舉 map 在最外層 map 中的 key。
key:代表枚舉的 key 或值字段。
desc:代表枚舉的描述字段。
深入互動
與 ChatGPT 進行更深入的交流,詢問它關于代碼優化、異常處理等方面的建議。它可以幫你找到更好的解決方案。
接下來需要與 ChatGPT 進一步交流,讓 ChatGPT 將之前生成的代碼進行優化。
EnumInfo 注解優化前:
?優化后:
逐步完善
逐步引導 chatgpt 完善框架
在 ChatGPT 的幫助下,逐步完善你的框架。親自動手編寫代碼,與 ChatGPT 一起探討每個細節。
最后可以和 ChatGPT 一步步交流,讓它幫你構建一個完整的框架。
??最終慢慢與 ChatGPT 不斷對話迭代之后將框架的核心類生成,迭代過程由于太長故省略。
框架核心類說明
在 ChatGPT 給出核心代碼之后,我參考 Spring 模塊設計最終初版框架類如下:
PackageScanner:用于掃描給定包中帶有指定注解的類的實用工具類。
PropertiesUtils:提供操作屬性文件的實用方法的工具類。
EnumInfo:用于標注枚舉類的注解,指定枚舉項的名稱、key 字段和 desc 字段信息。 通過在枚舉類上添加該注解,可以為枚舉項建立索引映射,并指定用于查找 key 和 desc 的字段名稱。
EnumContext:枚舉上下文類,用于管理枚舉定義信息并提供獲取枚舉信息的方法。
EnumContextFactory:枚舉上下文工廠類,用于創建和獲取單例的枚舉上下文對象。
EnumDefinition:表示枚舉定義的類,用于存儲枚舉類的信息。
EnumDefinitionRegistry:枚舉定義注冊接口,用于注冊、查詢和管理枚舉定義。
DefaultEnumFactory:默認的枚舉定義工廠類,實現了 EnumDefinitionRegistry 接口。
??看到這使用 ChatGPT 編寫框架部分已經完成了。大件可以使用 chatgpt 開發自己的 JAVA 框架。但要想把框架實際應用到生產還需要做一些收尾流程。
框架使用測試
在于 ChatGPT 交流,完成框架編寫之后需要將框架應用到實際項目中。
筆者業務系統管理端在進行前后端分離的過程中,研發們發現有許多枚舉類對應的枚舉描述需要給前端返回。
1)一開始設想的是每個枚舉類都寫代碼給前端封裝返回文字。但是由于筆者業務系統配置項過多,每個配置項都寫代碼太過麻煩。
2)于是研發們想能否使用一個統一的接口給前端返回枚舉類對應的描述,前端只需要輸入枚舉類名稱就可以獲得對應的枚舉 key 和描述的映射關系。
于是我們創建了一個接口,定義了一個 Map 對象給前端返回枚舉類的 key 和描述的對應關系。但是由于筆者業務系統的渠道配置還是太多了。使用這種方式我們需要初始化這個 Map。初始化 Map 代碼如下:
public HashMap<String, Map<Integer, String>> initEnumMap() {
enumMap = new HashMap<>();
enumMap.put("前端獲取枚舉map的key", XXXEnum.getEnumMap());
enumMap.put("前端獲取枚舉map的key", XXXEnum.getEnumMap());
enumMap.put("前端獲取枚舉map的key", XXXEnum.getEnumMap());
return enumMap;
}
可見,每新增一個枚舉類。我們都需要在靜態代碼塊中將映射關系放入 map 中。并且枚舉類需要新增一個獲取 key 和描述的映射關系方法。這樣還是太麻煩了。并且后續新增映射關系還得更改這個類的代碼。
能否將 map 初始化的步驟和枚舉類創建 map 的步驟省略呢?
3)于是我們設想定義一個注解。使用這個注解標記的類,框架掃描這些類。并生成獲取枚舉 key 和描述的映射關系的方法。最終完成初始化 Map 的過程。對外只提供獲取總枚舉 Map 的方法即可。用戶無需關心 Map 如何構建。使用這個框架之后,筆者業務系統這個接口的代碼如下:
/**
* 獲取枚舉
* @param enumKey 枚舉key
* @return 返回值 Map<Integer,String>;code,描述
*/
@RequestMApping("/getEnum")
public Result<Map<String, Map<String, String>>> getEnum(String enumKey) {
try {
// 獲取枚舉上下文對象
EnumContext enumContext = EnumContextFactory.getEnumContext();
// 獲取枚舉map
newEnumMap = enumContext.getEnumIndexMap();
// buid映射從ducc中獲取,所以需要手動設置
newEnumMap.put(BUID.getKey(), getBuIdMap());
} catch (Exception e) {
log.error("獲取枚舉map出錯!enumKey:{}", enumKey, e);
return Result.createFAIl(e.getMessage());
}
// 如果枚舉key為空則返回全部
if (StringUtils.isBlank(enumKey)) {
return Result.createWithSuc(newEnumMap);
}
// 如果枚舉key不為空則返回指定值
Map<String, Map<String, String>> resultMap = new HashMap<>();
resultMap.put(enumKey, newEnumMap.get(enumKey));
return Result.createWithSuc(resultMap);
}
4)注解類代碼如下:
在這舉個測試枚舉類的例子
@EnumInfo(name = "StatusEnum", key = "code", desc = "description")
public enum StatusEnum {
SUCCESS(200, "Success"),
ERROR(500, "Error");
private final int code;
private final String description;
StatusEnum(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}
以后新增一個枚舉類只需要標記 @EnumInfo (name = "StatusEnum", key = "code", desc = "description")。將枚舉類的 name ,key 字段名稱和描述字段名稱指定即可。無需修改接口的代碼即可給前端返回該枚舉的 key 和描述的映射關系。極大的減少了研發聯調時間及測試回歸時間。
框架性能壓測
框架應用到實際生產項目中,需要對 ChatGPT 輔助編寫的框架進行充分的測試驗證。同時也要對框架的性能進行測試,知道框架的瓶頸。常見的接口壓測工具有 LoadRunner 和 Apache JMeter 等。任選一種壓測工具進行壓測即可。
筆者將框架應用到項目中對外暴露了一個接口,該接口在 4C4G 機器配置下,單機最高可支持 1000QPS,在 1000QPS 下,單機 CPU 使用率達到 30%,系統負載接近 0.9,內存使用率與壓測前無明顯變化。
作者:京東零售 王鳳璽
來源:京東云開發者社區 轉載請注明來源