容器是什麼?數據結構
水壺是容器,水壺中存放着水,等咱們須要水了,直接用.net
Spring中的ApplicationContext是容器,裏面存放着各類Bean,等咱們須要了直接用,而且能夠建立管理Beancode
Hierarchy是Log4j的容器,它裏面存放着各類Logger? 用來管理各類Logger?blog
Hierarchy是什麼?繼承
從字面上看:ci
n. 層級;等級制度。文檔
log4j的文檔說明:get
This class is specialized in retrieving loggers by name and also maintaining the logger hierarchyio
用來根據名稱獲取Logger並維持logger等級。看來是咱們想一想的那樣,存放着各類Logger並管理,等咱們須要的時候還能夠從中獲取。class
Hierarchy既然是容器,談到容器,就如上面所說的水壺、Spring中的ApplicationContext以及Java中的集合類。他們的核心功能就是存和取。
簡單認識下Hierarchy字段
容器存的是Logger,每一個Logger都有全局惟一的名稱,也能夠說每一個名稱只對應一個Logger實例,全部Logger均以名稱爲key存儲在HashTable中,而且還根據名稱組裝成以RootLogger爲根的一棵樹,樹的層次由Logger的name決定,以"."分隔。以下圖所示,HashTable和Logger中的parent維護了以RootLogger爲根節點的樹。
因爲Log4j容許先存放子節點,而後再存放父節點,這裏就會涉及到子節點的父節點更細問題,下面會分先存放父節點和子節點兩種狀況進行分析,在開始以前先來認識下ProvisionNode.
ProvisionNode:
Provision類實際上就是一個Vector(經過繼承Vector實現)。當ChildLogger先創建,未能找到parent的時候,log4j會預先創建一個ProvisionNode,並將ChildLogger添加到ProvisionNode中,當實際的ParentLogger建立時,再將全部的ChildLogger從ProvisionNode轉移到Parent中.
再存放Logger(x.y.z),在HashTable中沒有找到對應的Logger,調用LoggerFactory獲得Logger(x.y.z);x.y.z的parent有x.y、x、root,在HashTable中能找到x.y對應的Logger,設置Logger(x.y.z)的parent爲Logger(x.y)
依次類推...
存放Logger(x.y.z)
查詢HashTable中不存在,Logger(x.y.z),建立Logger(x.y.z)
遍歷父節點x.y/x,不存在Logger(x.y)和Logger(x),建立P(x.y)和P(x),並添加Logger(x.y.z)到vector容器中,並存儲在HashTable中
沒有找到父節點對應的Logger,設置Root爲父節點
存放Logger(x.y)
查詢HashTable,獲得P(x.y),建立Logger(x.y)
遍歷P(x.y)的Vector(存放子節點)更新其parent
遍歷Logger(x.y)父節點x,不存在Logger(x),則把Logger(x,y)添加到P(x)對應的vector中
沒有找到Logger(x.y)父節點對應的Logger,設置RootLogger爲其父節點
存放Logger(x)
以此類推...
從上面的案例能夠看出相同的名稱獲得的Logger實例必定是相同,並且每一個Logger都有一個Parent,根節點是RootLogger。
咱們經常用下面的代碼得到Logger,相信經過上面的講解,你已經知道怎麼獲取的了。其實就是根據Class的徹底限定名,去HashTable中獲取,若是不存在則建立,而後更新parent以及child.
private static Logger logger = Logger.getLogger(Test.Class);
參考