(本章主要講解Java裡面比較核心的一塊內容——異常處理,Java異常處理機制,一致都是比較複雜的一塊,而很多時候如果寫程式的時候能夠適當地注意對應的一些異常處理情況,那麼就會在開發過程節省一大部分時間,最常見的情況就是輔助進行調試以及維護工作以及提高系統的容錯性和穩定性。這一章和前邊類和對象章節不一樣,這一章可能涵蓋的內容沒有前邊那章多,但是我會盡量保證在整篇文章裡面把開發過程中需要注意到的與異常有關的細節問題以及對應的開發經驗寫入本文,而本章的出發點是異常處理,核心內容還涵蓋了測試、調試、以及部署等相關內容以及。如果有筆誤的地方,請來Email指點:
silentbalanceyh@126.com,謝謝)
本章目錄
1.Java異常處理
2.異常處理心得 3.
斷言的使用
4.
Java中的日誌(JDK1.4 Logging Framework)
5.第三方日誌庫(Log4j、Commons Logging Framework)
5.第三方日誌庫(Log4j,Commons Logging Framework)
前邊介紹了官方的日誌架構JDK 1.4 Logging Framework,接下來介紹兩個第三方的日誌架構Log4j和Commons Logging Framework,這三個日誌架構也是整個Java界使用最多的日誌架構。 下載地址:【直接複製就可下載】 http://apache.freelamp.com/logging/log4j/1.2.15/apache-log4j-1.2.15.zip http://labs.xiaonei.com/apache-mirror/logging/log4j/1.2.15/apache-log4j-1.2.15.zip
http://apache.etoak.com/logging/log4j/1.2.15/apache-log4j-1.2.15.zip i.Log4j: 1)基本簡介: Log4j是Apache的一個開放原始碼項目,通過使用Log4j,我們可以控制日誌資訊輸送的目的地是控制台、檔案、GUI組件、甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護進程等;我們也可以控制每一條日誌的輸出格式;通過定義每一條日誌資訊的層級,我們能夠更加細緻地控制日誌的產生過程。最令人感興趣的就是,這些可以通過一個設定檔來靈活地進行配置,而不需要修改應用的代碼。 此外,通過Log4j其他語言介面,您可以在C、C++、.Net、PL/SQL程式中使用Log4j,其文法和用法與在Java程式中一樣,使得多語言分布式系統得到一個統一一致的日誌組件模組。而且,通過使用各種第三方擴充,您可以很方便地將Log4j整合到J2EE、JINI甚至是SNMP應用中。 整體上講,Log4j中有三個最主要的核心組件:Logger、Appender和Layout,不僅僅如此,它同樣允許開發人員自訂多個Logger,每個Logger有自己的名字,Logger之間通過名字來表示隸屬關係。但是有一個Logger稱為Root,這個Logger不能通過名字來檢索,但是可以直接使用Logger.getRootLogger()擷取,其他的Logger都可以使用Logger.getLogger(String name)方法擷取 Logger: 在執行應用程式時,接收日誌語句產生的日誌請求。它是一種重要的Tlog組件, 可以通過 log4j API 的 logger 類對其進行訪問。它的方法有:debug、info、warn、error、fatal 和 log。這些方法用於記錄訊息。 Appender: 管理日誌語句的輸出結果。執行日誌語句時,Logger 對象將接收來自日誌語句的記錄請求。此請求是通過 logger 發送至 appender 的。然後,Appender 將輸出結果寫入到使用者選擇的目的地。對於不同的日誌目的地,提供不同的 appender 類型。這些 appender 包括:用於檔案的 file appender、用於資料庫的 JDBC appender 和用於 SMTP 伺服器的 SMTP appender。
Layout: 用於指定 appender 將日誌語句寫入日誌目的地所採用的格式。appender 可以用來格式化輸出結果的各種布局包括:簡單布局、模式布局和 HTML 布局。 [1]先看看Log4j的包目錄結構: org.apache.log4j:log4j主要的類、介面以及特殊的Appender類、Layout、Level和Logger org.apache.log4j.spi:包含了針對SPI的一部分擴充【SPI——System Programming Interface】 org.apache.log4j.chainsaw:基於Java Swing的一個GUI日誌查看器:
org.apache.log4j.config:用來設定或者擷取某些組件的相關屬性 org.apache.log4j.helpers:僅僅被log4j庫內聯使用的多個Class的集合,一般情況下不對外 org.apache.log4j.jdbc:一個Appender用來記錄JDBC串連的相關事件 org.apache.log4j.jmx:在JMX開發的時候可以配置的基於JMX的日誌記錄,但是目前該包裡面的類還不是特別穩定 org.apache.log4j.lf5:【目前很少用,我也不知道這部分用途,沒用過】 org.apache.log4j.net:用來進行遠程日誌記錄的Appender,主要用於JMS、SMTP以及基於Socket的日誌記錄,用於向一個log4j伺服器發送日誌進行遠端日誌記錄 org.apache.log4j.nt:Java本地介面的應用【JNI】,介面用Java,實現用C代碼,用來記錄Windows NT系統事件日誌的Appender組件 org.apache.log4j.or:根據物件類型來對對象進行Render操作的協助類 org.apache.log4j.performance:效能測試代碼 org.apache.log4j.xml:包含了多個XML組件,使用DOM Tree的結構在Log4j環境裡面用來記錄XML格式的日誌 org.apache.log4j.varia:包含了多個Appender以及Filters和其他相關組件 [2]Log4j的安裝: Log4j下載下來過後需要進行簡單的安裝,先保證原來的系統內容和Java環境是正常的: 下載log4j的jar包,上邊已經提供了下載地址 將這些包解壓到一個目錄裡面,【*:一般對於開發人員最好將jar的包分類放在不同的目錄下邊方便使用。】 將包下邊的log4j-1.2.15.jar放入開發的CLASSPATH裡面,關於Java裡面CLASSPATH的一些問題留到開發用Java裡面去講解 還需要下載兩個輔助解析XML的jar,下載地址http://archive.apache.org/dist/xml/xerces-j/,這裡我下載的最新版本2.9.0,取出裡面的xercesImpl.jar和xml-apis.jar兩個jar檔案放到CLASSPATH裡面。【*:在IDE環境下有專程針對CLASSPATH的設定,這種情況防止jar衝突最好的方式就是保持CLASSPATH裡面只有java標準的環境】 2)Log4j的核心概念: [1]Log4j中的Logger: Logger在Log4j中是一個很核心的概念,它是日誌進程裡面的核心組件,在Log4j裡面,Logger總共分為六個日誌記錄層級,其定義位於org.apache.log4j.Level類裡: TRACE:這種細粒度資訊時間不僅僅針對調試, DEBUG:指出細粒度資訊事件對調試應用程式是非常有協助的,該層級的日誌主要用於輔助開發人員調試; INFO:該層級表明訊息上細粒度上突出強調了應用程式的運行過程 WARN:表明有可能會出現潛在錯誤的情形 ERROR:表明雖然程式發生了錯誤事件,但是仍然不影響系統的繼續運行 FATAL:該層級表明了每個嚴重的錯誤時間,將會導致應用程式的退出。 根據API裡面的描述還存在兩個很特殊的層級: ALL:這是最低層級,用於開啟所有的日誌記錄 OFF:這是最進階別,用於關閉所有的日誌記錄 一般情況下,推薦開發過程只使用ERROR、WARN、INFO、DEBUG四個層級,下圖說明了這幾個層級相互之間的關係:
從上圖可以知道,只有當日誌記錄器Logger的記錄層級高於或者等於輸出訊息的等級的時候,該日誌訊息才會被輸出。預設情況下,Logger的層級是Debug,如果我們需要建立一個Logger,有以下幾種方式: 建立根日誌器: Logger logger = Logger.getRootLogger(); 建立一個新的日誌器: Logger logger = new Logger("MyLogger"); 建立一個基於類的日誌器: Logger logger = new Logger(MyClass.class); 在Log4j裡面設定一個日誌的層級使用語句: logger.setLevel(Level.DEBUG); 【*:在1.2版本之前,Log4j裡面沒有使用Logger類,主要是使用Category類,從版本1.2開始才使用Logger類,就上邊的方式建立Logger】 這裡先看一段代碼,然後對Category進行一個詳細說明,實際上從版本1.2開始Category和Logger是父子關係,Logger從Category類繼承而來;在該版本之前我們一般使用Category來建立日誌記錄器,在前邊的版本裡面Category就等同於現在我們所見到的Logger。在版本1.2中,Category被標記為deprecated,而直接使用Logger替代它,一般情況下Java裡面被標記為deprecated的方法和類都有替代方法以及類來進行對應功能的版本更新,我們一般在開發過程中盡量避免使用標記為deprecated的類或者方法。下邊的代碼是升級的改動: // 被拋棄的代碼形式: Category cat = Category.getInstance("foo.bar"); // 目前使用的建立Logger的形式: Logger logger = Logger.getInstance("foo.bar"); 為了使得上邊的圖形裡面的內容更加容易理解,這裡提供另外一段代碼: package org.susan.java.logging;
import org.apache.log4j.Level; import org.apache.log4j.Logger;
class Foo{}
public class Log4jLevelTester { public static void main(String args[]){ Logger logger = Logger.getLogger(Foo.class); logger.setLevel(Level.INFO);
// 該請求是被允許的,因為 WARN >= INFO logger.warn("Low fuel level.");
// 該請求時背禁止的,因為 DEBUG < INFO logger.debug("Starting search for nearest gas station."); } } 上邊這段代碼很好說明了logger在對待LEVEL的時候的用法,在setLevel的時候Logger設定了日誌器本身的Level,然後在使用裡面對應的warn、debug方法的時候會判斷使用的方法和日誌記錄器設定的Level進行詳細的比較,當滿足上邊圖示的判斷條件的時候才會輸出日誌資訊。在這裡還有一點需要注意的是方法warn和debug,這兩個方法都不是Logger類所具有的方法,而是從它的父類繼承過來的Category的方法,在使該方法的時候會針對我們最初設定的日誌的Level進行一個比較和判斷,最終決定是否要被記錄下來。那麼在環境配置好的情況下,我們執行該程式。 【異常】這裡會遇到一個初學Log4j的常見問題,我們會發現控制台只有這句話輸出: log4j:WARN No appenders could be found for logger (org.susan.java.logging.Foo). log4j:WARN Please initialize the log4j system properly. 這句話的意思是在系統內容裡面沒有找到我們所需要的設定檔,一般理解是缺乏log4j.properties屬性檔案,在此處,如果我們不使用設定檔的方式就將下邊的代碼修改成: package org.susan.java.logging;
import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Level; import org.apache.log4j.Logger;
class Foo{}
public class Log4jLevelTester { public static void main(String args[]){ BasicConfigurator.configure(); Logger logger = Logger.getLogger(Foo.class); logger.setLevel(Level.INFO);
// 該請求是被允許的,因為 WARN >= INFO logger.warn("Low fuel level.");
// 該請求時背禁止的,因為 DEBUG < INFO logger.debug("Starting search for nearest gas station."); } }