這個(gè)題目可能有些危言悚聽,使用Spring的同行不用害怕,只是因?yàn)楣ぷ髦信龅揭恍﹩栴},才偶然想到這個(gè)問題。
首先要明確兩個(gè)問題:
1、系統(tǒng)隔離原則:
即系統(tǒng)間依賴應(yīng)該是清晰的,不因?yàn)橐粋€(gè)系統(tǒng)的故障影響其他系統(tǒng),甚至整個(gè)系統(tǒng)。
2、簡(jiǎn)單應(yīng)用習(xí)慣:
普通程序員只會(huì)處理checked Exception,負(fù)責(zé)任的程序員會(huì)處理被調(diào)用的函數(shù)可能拋出的異常(根據(jù)源碼或javadoc)
我們碰到一個(gè)情況:
使用Spring的 init 特性初試化一個(gè)bean--一個(gè)使用Qutarz的調(diào)度程序。初試化過程中會(huì)拋出RuntimeException,從而造成Spring容器的整個(gè)初試化失敗。首先我們修改了程序,捕獲了所有異常,隨后在編碼指南中加入了一句話:"所有使用Spring-init機(jī)制初試化的類必須在init中捕獲所有異常:Exception"。因?yàn)橹挥腥绱瞬拍鼙WC整個(gè)系統(tǒng)不會(huì)因?yàn)榫植繂栴}而完全癱瘓。
我覺得這是Spring對(duì)異常處理的一個(gè)悖論:
正方:底層異常都封裝成Runtime的,經(jīng)過幾次包裝--->簡(jiǎn)單應(yīng)用習(xí)慣--->異常被拋出領(lǐng)域?qū)?init場(chǎng)景下:由Spring處理)
反方: 一個(gè)類的失敗可以造成整個(gè)系統(tǒng)的失敗---->Spring被RuntimeException宕掉---->不符合系統(tǒng)隔離原則
當(dāng)然充分的測(cè)試可能可以解決這個(gè)問題:但是要注意,測(cè)試只能證明系統(tǒng)有bug,不能證明系統(tǒng)沒有bug。
解決方案:
1、好的設(shè)計(jì)習(xí)慣:將應(yīng)該隔離的系統(tǒng)隔離開-->使用不同的Spring配置文件.
2、接口層錯(cuò)誤處理:在接口層應(yīng)該盡量對(duì)可以處理的異常進(jìn)行處理,然后以合理的方式傳遞給上層.
PS:在與人交互的系統(tǒng)中都應(yīng)該給最終用戶合理的錯(cuò)誤提示,所以表現(xiàn)層應(yīng)該盡量捕獲非業(yè)務(wù)的RuntimeException給最終用戶更好的操作感受。