想學(xué)習(xí)架構(gòu)師構(gòu)建流程請?zhí)D(zhuǎn):Java架構(gòu)師系統(tǒng)架構(gòu)設(shè)計
1 編程規(guī)約
我們介紹了讓代碼規(guī)范的方案,下面我們就來說一下阿里的代碼規(guī)范文檔
業(yè)界公認的代碼規(guī)范手冊(國內(nèi))當屬阿里巴巴旗下出版的《Java 開發(fā)手冊》,經(jīng)過幾個版本的迭代,最新手冊為《Java 開發(fā)手冊》,更新時間為2022年2月3號。
手冊以 Java 開發(fā)者為中心視角,劃分為編程規(guī)約、異常日志、 單元測試、 安全規(guī)約、 MySQL 數(shù)據(jù)庫、 工程結(jié)構(gòu)、 設(shè)計規(guī)約七個維度,再根據(jù)內(nèi)容特征,細分成若干二級子目錄。根據(jù)約束力強弱及故障敏感性,規(guī)約依次分為強制、推薦、參考三大類。對于規(guī)約條目的延伸信息中,“說明” 對規(guī)約做了適當擴展和解釋;“正例” 提倡什么樣的編碼和實現(xiàn)方式;“反例”說明需要提防的雷區(qū), 以及真實的錯誤案例。
1.1 方法參數(shù)類型必須一致,不要出現(xiàn)自動裝箱拆箱操作
1.1.1 反例
這種操作很容易產(chǎn)生難以排查的NPE異常
/**
* 反例
* 容易出現(xiàn)空指針異常,如果參數(shù)為null就會拆箱失敗空指針錯誤
* 排查的時候很難排查,因為直接看代碼看起來不會出現(xiàn)空指針的。
* @param value
* @return
*/
public static int handel(Integer value) {
return value;
}
1.1.2 正例
入?yún)⒁约俺鰠?,和參?shù)傳遞類型是一致的
public static Integer handel(Integer value) {
return value;
}
1.2 SimpleDateFormat是線程不安全的
SimpleDateFormat 是線程不安全的類,一般不要定義為 static 變量,如果定義為 static, 必須加鎖,或者使用 DateUtils 工具類
1.2.1 反例
使用這種方式在多線程的情況下會報錯,或者出現(xiàn)數(shù)據(jù)不一致的情況
private static final SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1.2.2 正例
使用ThreadLocal的方式保證線程安全,或者使用
DateTimeFormatter
代替SimpleDateFormat
private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
1.3 使用equals方法應(yīng)該注意空指針
1.3.1 反例
如果object為null就會拋出NPE異常
object.equals("test");
1.3.2 正例
應(yīng)該使用常量或者確定的值來進行判斷equals
"test".equals(object);
或者使用
Objects.equals
Objects.equals(object1,object2)
2 異常日志
2.1 事務(wù)場景中如果異常被被捕獲要注意回滾
2.1.1 反例
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
try{
//some code
//db operation
}catche(Exception e){
}
}
}
2.1.2 正例
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
try{
//some code
//db operation
}catche(Exception e){
//捕獲處理后需要再將異常拋出
throw e;
}
}
}
2.2 不要在 finally 塊中使用 return
try 塊中的 return 語句執(zhí)行成功后,并不馬上返回,而是繼續(xù)執(zhí)行 finally 塊中的語句,如果此處存 在 return 語句,則在此直接返回,無情丟棄掉 try 塊中的返回點。
2.2.1 反例
這種情況下結(jié)果永遠返回的都是true,fanally中不要做返回操作
public static boolean getValue(String text) {
try {
return text.equals("123");
} finally {
return true;
}
}
2.2.2 正例
public static boolean getValue(String text) {
return "123".equals(text);
}
2.3 應(yīng)用中不可直接使用日志系統(tǒng)(Log4j、Logback)中的 API
在Java生態(tài)體系中,圍繞著日志,有很多成熟的解決方案,關(guān)于日志輸出,主要有兩類工具。
一類是日志框架,主要用來進行日志的輸出的,比如輸出到哪個文件,日志格式如何等,另外一類是日志門面,主要一套通用的API,用來屏蔽各個日志框架之間的差異的。
所以,對于Java工程師來說,關(guān)于日志工具的使用,最佳實踐就是在應(yīng)用中使用如Log4j + SLF4J 這樣的組合來進行日志輸出。
這樣做的最大好處,就是業(yè)務(wù)層的開發(fā)不需要關(guān)心底層日志框架的實現(xiàn)及細節(jié),在編碼的時候也不需要考慮日后更換框架所帶來的成本,這也是門面模式所帶來的好處。
請不要在你的Java代碼中出現(xiàn)任何Log4j等日志框架的API的使用,而是應(yīng)該直接使用SLF4J這種日志門面。
2.4 所有日志文件至少保存15天
所有日志文件至少保存15天,因為有些異常具備以“周”為頻次發(fā)生的特點,網(wǎng)絡(luò)運行狀態(tài)、安全相關(guān)信息、系統(tǒng)監(jiān)測、管理后臺操作、用戶敏感操作需要留存相關(guān)的網(wǎng)絡(luò)日志**不少于6個月**。
3 單元測試
3.1 好的單元測試必須遵守 AIR 原則
單元測試在線上運行時,感覺像空氣(AIR)一樣并不存在,但在測試質(zhì)量的保障上,卻是非常關(guān)鍵的,好的單元測試宏觀上來說,具有自動化、獨立性、可重復(fù)執(zhí)行的特點。
3.2 單元測試應(yīng)該是全自動執(zhí)行的,并且非交互式的
- 測試用例通常是被定期執(zhí)行的,執(zhí)行過程必須完全自動化才有意義。
- 輸出結(jié)果需要人工檢查的測試不是一個好的單元測試。
- 單元測試中不準使用
System.out
來進行人肉驗證,必須使用assert
來驗證。
3.3 單元測試是可以重復(fù)執(zhí)行的,不能受到外界環(huán)境的影響
單元測試通常會被放到持續(xù)集成中,每次有代碼check in時單元測試都會被執(zhí)行,如果單測對外部環(huán)境(網(wǎng)絡(luò)、服務(wù)、中間件等)有依賴,容易導(dǎo)致持續(xù)集成機制的不可用,為了不受外界環(huán)境影響,要求設(shè)計代碼時就把SUT的依賴改成注入,在測試時用spring 這樣的DI框架注入一個本地(內(nèi)存)實現(xiàn)或者Mock實現(xiàn)。
4 安全規(guī)約
4.1 用戶敏感數(shù)據(jù)禁止直接展示,必須對展示數(shù)據(jù)進行脫敏
中國大陸個人手機號碼顯示為:`137****0969`,隱藏中間 4 位,防止隱私泄露,以及用戶的身份證號碼,銀行卡號碼,用戶姓名等都需要進行脫敏處理
4.2 用戶請求傳入的任何參數(shù)必須做有效性驗證
說明:忽略參數(shù)校驗可能導(dǎo)致:
- page size 過大導(dǎo)致內(nèi)存溢出
- 惡意 order by 導(dǎo)致數(shù)據(jù)庫慢查詢
- 緩存擊穿
- 服務(wù)器端請求偽造(SSRF)
- 任意重定向
- SQL 注入,Shell 注入,反序列化注入
- 正則輸入源串拒絕服務(wù) ReDoS
5 MySQL 數(shù)據(jù)庫
5.1 表明命名規(guī)范
表名、字段名必須使用小寫字母或數(shù)字,禁止出現(xiàn)數(shù)字開頭,禁止兩個下劃線中間只出現(xiàn)數(shù)字。
數(shù)據(jù)庫字段名的修改代價很大,因為無法進行預(yù)發(fā)布,所以字段名稱需要慎重考慮,MySQL 在 Windows 下不區(qū)分大小寫,但在 Linux 下默認是區(qū)分大小寫,因此,數(shù)據(jù)庫名、表名、 字段名,都不允許出現(xiàn)任何大寫字母,避免節(jié)外生枝
- 一般以t_xxx來作為表名
- 一般以v_xxx來作為視圖名稱
5.2 表必備的幾個字段
- 創(chuàng)建人:標記記錄的初始創(chuàng)建人
- 創(chuàng)建時間:標記初始的創(chuàng)建人
- 修改人:標記修改人
- 修改時間:標記最后修改日期
- 版本號:用于統(tǒng)一化的樂觀鎖
6 工程結(jié)構(gòu)
6.1 線上應(yīng)用不要依賴 SNAPSHOT 版本
正式發(fā)布的類庫必須先去中央倉庫進行查證,使 RELEASE 版本號有延續(xù)性,且版本號不允許覆蓋升級。
6.2 注意POM坐標沖突
禁止在子項目的 pom 依賴中出現(xiàn)相同的 GroupId,相同的 ArtifactId,但是不同的Version。
在本地調(diào)試時會使用各子項目指定的版本號,但是合并成一個 war,只能有一個版本號出現(xiàn)在最后的lib 目錄中,曾經(jīng)出現(xiàn)過線下調(diào)試是正確的,發(fā)布到線上卻出故障的先例。
7 阿里規(guī)范插件安裝
這里面只列出來了幾個比較重要的,很有很多的規(guī)約沒有寫出來,為了讓大家碼代碼的效率更高,可以安裝阿里的代碼規(guī)范插件來約束自己凌亂的代碼
阿里規(guī)范插件GitHub地址:https://github.com/alibaba/p3c
7.1 IDEA安裝該插件步驟
打開IDEA,F(xiàn)ile-> Setteings->Plugins,在搜索欄搜索Alibaba,然后安裝,安裝完后點擊Restart IntelliJ IDEA重啟idea
7.2 使用
安裝好了,使用方法是:打開IDEA,點擊tools—>安裝的阿里編碼規(guī)約,可以選擇中英文切換,項目右鍵選擇編碼規(guī)約掃描就可以進行查看自己編碼哪些地方不夠好
7.3 檢查等級
檢查結(jié)果一共分三個等級
等級 | 驗證程度 | 備注 |
---|---|---|
Blocker | 嚴重 | 有明顯問題,影響功能以及性能 |
Critical | 危險 | 一般問題,遵循標準 |
Major | 主要 | 一般為建議 |
7.4 查看結(jié)果
可以通過結(jié)果查看一般存在的問題文章來源:http://www.zghlxwxcb.cn/news/detail-688625.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-688625.html
到了這里,關(guān)于Java阿里巴巴代碼規(guī)范的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!