某大型银行深化系统之二十:异常规范
生活随笔
收集整理的這篇文章主要介紹了
某大型银行深化系统之二十:异常规范
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
傳送門???輪子的專欄???轉(zhuǎn)載請注明???http://blog.csdn.net/leverage_1229
1異常拋出與捕捉規(guī)則
1.1任何拋出異常的方法必須先聲明異常
{// Constructorpublic MyClass( String name ) throws NullPointerException, llegalArgumentException {...}
} 1.2異常聲明后,調(diào)用異常對象的構(gòu)造器拋出異常
public MyClass( String name ) throws NullPointerException, IllegalArgumentException {if ( name == null )throw new NullPointerException( );if ( name.length == 0 )throw new IllegalArgumentException( );...
}? ? ? ? Java異常都從Throwable類繼承而來。1.3用try,catch聲明捕捉異常
try {MyClass newobj = new MyClass( name );
} catch ( NullPointerException e ) {// Do something about it
} catch ( IllegalArgumentException e ) {// Do something about it
}? ? ? ? 當try中的語句產(chǎn)生異常時,在異常處理函數(shù)捕捉了該異常而又沒有重新拋出異常時,則在執(zhí)行完處理函數(shù)后,將跳出發(fā)生異常的try塊,接著執(zhí)行下面的語句。當try中的語句產(chǎn)生異常時,在異常處理函數(shù)捕捉了該異常而又重新拋出異常時,則將把異常拋出到上一層,發(fā)生異常的語句之后的代碼將不執(zhí)行。如果沒處理相應(yīng)異常的處理函數(shù),將把異常拋出到上一層,發(fā)生異常的語句之后的代碼將不執(zhí)行。如果想捕捉所有異常,只要捕捉Exception異常就行。如果某段代碼不管是否發(fā)生異常都要執(zhí)行,那可把它放入finally塊中,以finally進行清理。2取得異常信息的幾個常用方法
String getMessage()、getLocalizedMessage 、toString()取得異常對象中的信息。void printStackTrace()、Throwable fillStackTrace()。printStackTrace打印出Throwable和其call stack trace;FillStackTrace則在調(diào)用點設(shè)立新的stack trace信息。
RuntimeException異常。RuntimeException及其子類所代表的異常我們在程序中不用進行捕捉,如果發(fā)生此類異常,Java會自動拋出相應(yīng)的異常對象。
3繼承中異常規(guī)則
3.1構(gòu)造函數(shù)中的異常規(guī)則
? ? ? ? 某個derived class構(gòu)造函數(shù)的“異常規(guī)格接口”可以比其所調(diào)用的父類的構(gòu)造函數(shù)的異常規(guī)格接口寬,但決不能變窄。? ? ? ? derived class的構(gòu)造函數(shù)必須在自己的異常規(guī)格中聲明所有base class構(gòu)造函數(shù)的異常規(guī)格中所聲明的異常。
? ? ? ? 在derived class的構(gòu)造函數(shù)的異常規(guī)格中還可以聲明新的異常,即聲明在base class構(gòu)造函數(shù)的異常規(guī)格中沒有聲明的異常。
3.2非構(gòu)造函數(shù)的異常規(guī)則
? ? ? ? 某個函數(shù)的“異常規(guī)格接口”在繼承和重載中可以變窄,但決不能變寬。要覆寫base class的函數(shù)時,如果被覆寫函數(shù)(base class中的函數(shù))的異常規(guī)格中聲明了異常,那么覆寫函數(shù)(derived class中覆寫了base class中的函數(shù)的那個函數(shù))的異常規(guī)格中可以聲明:與被覆寫函數(shù)完全相同的異常;
被覆寫函數(shù)異常規(guī)格中的部分異常或其子類異常;
不聲明異常規(guī)格。
3.3.產(chǎn)生對象的異常規(guī)則
? ? ? ? 在產(chǎn)生一個對象時,捕捉的是產(chǎn)生對象時所調(diào)用的構(gòu)造函數(shù)中所聲明的異常。3.4.函數(shù)調(diào)用時的異常規(guī)則
? ? ? ? 當把一個對象向上轉(zhuǎn)型為它的base class時,并通過轉(zhuǎn)型后的reference進行函數(shù)調(diào)用時,我們要捕捉的是其base class的異常聲明。? ? ? ? 當用對象的原始類型來調(diào)用函數(shù)時,只需捕捉所調(diào)用的覆寫函數(shù)的異常。
4異常分類
4.1.Checked Exception
? ? ? ? Checked Exception是指那些需要程序顯式的處理(捕獲或者繼續(xù)拋出)的異常。在項目中Checked Exception主要可以分為以下三種:4.1.1BizException
? ? ? ? 項目自己定義的業(yè)務(wù)異常,BizException下繼承了若干個子異常。也就是說BizException是所有項目自定義異常的根類。4.1.2RollbackableBizException
? ? ? ? 項目自己定義的業(yè)務(wù)異常,是BizException的子類。4.1.3Other Checked Exception
? ? ? ? 其他非本項目定義的Checked Exception類異常4.2.Unchecked Exception
? ? ? ? Unchecked Exception是指那些不需要程序進行顯式處理(捕獲或繼續(xù)拋出)的異常,如果程序需要處理這類異常則其處理方式和Checked Exception一樣。在項目中Unchecked Exception 主要可以分為以下兩類:4.2.1DataAccessException
? ? ? ? 這類異常主要是Spring框架定義的數(shù)據(jù)訪問類異常,其具體類型根據(jù)數(shù)據(jù)庫的不同和數(shù)據(jù)庫所產(chǎn)生的錯誤的不同而不同。該類異常描述了數(shù)據(jù)庫訪問過程中所產(chǎn)生的錯誤。其下還有若干個子類異常,下面列出了這些異常:CleanupFailureDataAccessException:數(shù)據(jù)訪問操作之后無法正常執(zhí)行清除工作,比如JDBC訪問之后無法正常關(guān)閉Connection。
ConcurrencyFailureException:并發(fā)時可能出現(xiàn)此類異常,其下有若干子類異常來標識樂觀鎖和獲取鎖失敗這兩類異常信息。
OptimisticLockingFailureException:在違反了樂觀鎖機制的情況下會拋此異常
PessimisticLockingFailureException:違反悲觀鎖機制的情況下會拋出此異常。此異常是由SQLException轉(zhuǎn)換過來的。
CannotAcquireLockException:無法獲取鎖異常,一般在數(shù)據(jù)更新時獲取鎖失敗時拋出
DeadlockLoserDataAccessException:當一個并發(fā)進程進入死鎖鏈,通常需要拋出異常并回滾該進程產(chǎn)生的事務(wù) 。
DataAccessResourceFailureException:當訪問某個資源失敗時拋出此類異常,比如無法用JDBC與數(shù)據(jù)庫之間建立連接。其下有如下幾個子類
CannotCreateRecordException:由于連接器(Connector)內(nèi)部原因造成創(chuàng)建CC I(Common Client Interface)記錄失敗時拋出此異常。
CannotGetCciConnectionException:嚴重異常,無法通過CCI(Common Client Interface)連接EIS(企業(yè)信息系統(tǒng))拋出此異常。
CannotGetJdbcConnectionException:嚴重異常,無法通過JDBC連接到關(guān)系數(shù)據(jù)庫(RDBMS)。
DataIntegrityViolationException:當向數(shù)據(jù)庫插入一條數(shù)據(jù)或修改數(shù)據(jù)庫中的數(shù)據(jù)時違反了數(shù)據(jù)庫的完整性約束時拋出此異常。
DataRetrievalFailureException:當無法獲取預想的數(shù)據(jù)時拋出此異常。其下有若干子異常。
IncorrectResultSizeDataAccessException:當獲取的數(shù)據(jù)數(shù)量不是預想的數(shù)量的時候拋出此異常,比如預想獲取到1條數(shù)據(jù),但是獲得了0條或者多條數(shù)據(jù)時拋出此異常
LobRetrievalFailureException:LOB無法被獲取的時候拋出此類異常
ObjectRetrievalFailureException:通過映射對象(Object)的標識符來獲取映射對象失敗。
HibernateObjectRetrievalFailureException:將Hibernate和 UnresolvableObjectException, ObjectNotFoundException, ObjectDeletedException和WrongClassException轉(zhuǎn)換為此異常。
InvalidDataAccessApiUsageException:當錯誤的使用了API的時候拋出此異常
InvalidDataAccessResourceUsageException:當恰當?shù)脑L問數(shù)據(jù)時出現(xiàn)此異常,比如,SQL語法不正確。其下有多個子異常類。
BadSqlGrammarException:定義的SQL語句是非法的,有語法錯誤的時候拋出此異常,一般情況下都是由一個SQLException引起的。
CciOperationNotSupportedException:當連接器(Connector)不支持特定的CCI(Common Client Interface)操作的時候拋出此異常
HibernateQueryException:當HQL(Hibernate的數(shù)據(jù)庫查詢語句)語句出現(xiàn)錯誤時拋出此異常。
IncorrectUpdateSemanticsDataAccessException:當更新數(shù)據(jù)庫數(shù)據(jù)時出現(xiàn)非預想的結(jié)果,這個時候數(shù)據(jù)庫的事務(wù)還沒有回滾。比如預想修改1條數(shù)據(jù),但實際修改了3條數(shù)據(jù)。
InvalidResultSetAccessException:訪問結(jié)果集不合法,比如非法的字段名等等。
RecordTypeNotSupportedException:當由于連接器(Connector)不支持預想的CCI記錄(record)類型而造成創(chuàng)建一個CCI 記錄(record)的失敗的時候拋出此異常。
TypeMismatchDataAccessException:當Java類型與數(shù)據(jù)庫(RDBMS)的類型不匹配的時候出現(xiàn)此異常。
UncategorizedDataAccessException:無法分類的異常,其下有若干子異常
HibernateJdbcException:此異常是對Hibernate的JDBC異常的簡單包裝。
HibernateSystemException:當發(fā)生其他一些Hibernate錯誤是否拋出此異常,這些錯誤與org.springframework.dao中所定義的異常無法匹配
SQLWarningException、UncategorizedSQLException:無法分類的SQLException
4.2.2Other RuntimeException
? ? ? ? 其他類型的RuntimeException,例如:NullPointException等。5異常使用原則
? ? ? ? 使用異常主要是為了報告系統(tǒng)運行中出現(xiàn)的非正常情況。目前異常使用的方法有兩種。一種是使用不同的異常類來表示不同的異常,這些異常類的類名就表達了系統(tǒng)所處的非正常狀態(tài)。另一種是系統(tǒng)中出現(xiàn)的所有異常都用很少的幾個異常類來表示,通過這些異常類中Message來表達具體的異常信息。項目主要使用的的是后一種方法。但在某些主要的子系統(tǒng)或與外系統(tǒng)交互時也會采用一些第一種方法。? ? ? ? Message主要由兩部分組成Key和Param[],其中key的命名規(guī)則為:級別(1位)_模塊名(可選)_邏輯名,其中級別主要分為Warn(W)和Error(E)兩個級別。模塊名:指應(yīng)用功能的名稱。邏輯名:從某種角度上來說可以理解為異常的編碼。Param[]是具體的異常信息的參數(shù)。其具體使用方法如下,首先應(yīng)用程序從異常中獲取Message,然后從Message中獲取key值,根據(jù)key值從resource文件中獲得異常描述信息,將Param[]通過填空形式放入獲得異常描述信息中形成一個完整的異常描述信息。
5.1Checked Exception
? ? ? ? 根據(jù)是否需要事務(wù)作RollBack操作而使用不同類型的異常。5.1.1RollbackableBizException
? ? ? ? 需要事務(wù)RollBack則拋出RollbackableBizException。5.1.2BizException
? ? ? ? 如果不需要事務(wù)作RollBack操作則拋出BizException。5.1.3Other Checked Exception
? ? ? ? 在項目的應(yīng)用程序中只負責處理這類異常,不產(chǎn)生或使用這類異常。5.2Unchecked Exception
? ? ? ? 鼓勵應(yīng)用程序重用一些通用的UncheckedException異常,如IllegalArgumentsException, NullPointException等。5.2.1DataAccessException
? ? ? ? 大多數(shù)情況下這類異常應(yīng)用程序不用關(guān)心,特別是DAO類的對象不用關(guān)心這類異常。它是Spring框架所拋出的數(shù)據(jù)庫訪問的異常。5.2.2Other RuntimeException
6異常處理原則
? ? ? ? 異常處理需要遵循幾點基礎(chǔ)原則:第一,能處理則進行處理和關(guān)心的異常,不能處理或不關(guān)心的異常則繼續(xù)拋出。決不允許出現(xiàn)捕獲異常但又不做任何處理或拋出操作,這樣會丟失異常信息。
第二,異常拋出源需要在拋出異常之前將異常寫入日志中。以備進行檢查。
應(yīng)用程序所處層次的不同其對異常的處理也有所差別。下面列出了每個層次的應(yīng)用程序在處理異常的一些原則。
? ? ? ? 下圖是項目中異常使用的一個圖釋:
6.1web layer(展示層)
? ? ? ? 該層將從Business layer獲取的異常根據(jù)異常所傳遞的消息的不同來區(qū)分當前異常是否可恢復。這里指的可恢復是指當出現(xiàn)異常后操作人員可以通過改變輸入來解決出現(xiàn)的異常。按照可恢復性的不同,該層應(yīng)用對異常的處理也有所區(qū)分。具體操作過程中該層根據(jù)獲取異常Message來確定處理的方式。如果Message的級別是Warn則需要將異常信息顯示到操作員錄入頁面并保留上次錄入信息,如果Message級別是Error則需要將信息轉(zhuǎn)向?qū)iT的異常顯示頁面顯示異常信息。6.1.1可恢復異常
這類異常處理的時候應(yīng)將異常信息顯示在用戶輸入的頁面并保留相關(guān)的輸入信息,以便讓操作員通過修改輸入來糾正異常。6.1.2不可恢復異常
? ? ? ? 該類異常由于無法通過簡單的改變操作員的輸入來進行糾正,因此這類異常也比較嚴重。需要將該類異常的信息轉(zhuǎn)發(fā)到專門的異常信息顯示頁面上。6.2Business layer(業(yè)務(wù)層)
? ? ? ? 該層可以分為UCC(用例控制)層和Service(服務(wù))層。對于該層的異常處理也應(yīng)該分成兩部分來看待。6.2.1UCC Layer(UCC層)
? ? ? ? 該層除了負責處理本層所產(chǎn)生的異常外還要負責Service層所拋的所有異常。對于其根據(jù)獲取的異常的類型來做相應(yīng)的處理。一般情況下對于從Service層獲取的異常都是再次拋出,但在拋出前需要控制事務(wù)是否需要RollBack。如果獲取的錯誤是RollbackableException和UnChecked Exception則需要事務(wù)RollBack操作,如果是BizException則需要根據(jù)具體業(yè)務(wù)用例來確定是否需要事務(wù)RollBack,但原則是在拋出異常之前如果已經(jīng)發(fā)生了數(shù)據(jù)庫的Create、Update、delete等修改類型的操作則需要進行RollBack操作,否則則不需要RollBack。UCC層可以處理除了Other Checked Exception以外的所有異常類型。6.2.2Service Layer(服務(wù)層)
? ? ? ? Service層來除了負責處理自身處理過程中所產(chǎn)生的異常還要負責Integration Layer所拋出的異常的處理。一般情況下不需要處理Unchecked Exception,但如果業(yè)務(wù)需要也可以捕獲Unchecked Exception并作相應(yīng)的處理。Service所能夠處理的異常類型是本文所提到的所有類型的異常。6.3Integration layer(整合層)
? ? ? ? 整合層根據(jù)數(shù)據(jù)源類型的不同異常的處理原則也不同。6.3.1數(shù)據(jù)庫
? ? ? ? 當數(shù)據(jù)源為數(shù)據(jù)庫的時候,應(yīng)用程序不需要捕捉數(shù)據(jù)庫的異常或者Hibernate產(chǎn)生的異常(這些工作都有Spring框架完成)。在該層處理過程中如果出現(xiàn)異常則此類異常的嚴重等級都比較高,都需要做事務(wù)的RollBack操作。因此在這里出現(xiàn)異常都使用DataAccessException異常,當然具體異常類型可以為DataAccessException下的一個字類型。6.3.2其他外部系統(tǒng)
? ? ? ? 數(shù)據(jù)源為其他外部系統(tǒng)的時候,該層對外部系統(tǒng)所產(chǎn)生的異常進行相應(yīng)的封裝。封裝建議按照用異常類型來區(qū)分是什么異常的形式進行。這里拋出的異常一般都是特定的異常不是BizException類型的。Service在接收到該層拋出的異常以后根據(jù)異常的類型裝換成相應(yīng)Message放入BizException中重新拋出或者自己消化,但根據(jù)需要的不同也可以將異常直接重新拋出。轉(zhuǎn)載于:https://www.cnblogs.com/innosight/archive/2013/05/27/3271244.html
總結(jié)
以上是生活随笔為你收集整理的某大型银行深化系统之二十:异常规范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS中vsftp安装与配置
- 下一篇: 王者荣耀未成年可以全额退款吗?