zoukankan      html  css  js  c++  java
  • Log4j容器深入探究

    1.思考

    容器是什么?

    • 水壶是容器,水壶中存放着水,等我们需要水了,直接用

    • Spring中的ApplicationContext是容器,里面存放着各种Bean,等我们需要了直接用,并且可以创建管理Bean

    • Hierarchy是Log4j的容器,它里面存放着各种Logger? 用来管理各种Logger?

    Hierarchy是什么?

    从字面上看:

    n. 层级;等级制度。

    log4j的文档说明:

    This class is specialized in retrieving loggers by name and also maintaining the logger hierarchy

    用来根据名称获取Logger并维持logger等级。看来是我们想想的那样,存放着各种Logger并管理,等我们需要的时候还可以从中获取。

    2.Hierarchy 容器

    Hierarchy既然是容器,谈到容器,就如上面所说的水壶、Spring中的ApplicationContext以及Java中的集合类。他们的核心功能就是存和取

    简单认识下Hierarchy字段

    2.1 存储数据结构

    容器存的是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中.

    2.1.1 先存放父节点,再存放子节点
    • 先存放RootLogger

    • 再存放Logger(x),在HashTable中没有找到对应的Logger;调用LoggerFactory得到Logger(x),x的parent是Root

    • 再存放Logger(x.y),在HashTable中没有找到对应的Logger;调用LoggerFactory得到Logger(x.y),x.y的parent有x、root,在HashTable中能找到x对应的Logger,设置Logger(x.y)的parent为Logger(x)

    • 再存放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)

      依次类推...

    2.1.2 先存放子节点,再存放父节点
    • 先存放RootLogger

    • 存放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。

    2.2 获取Logger

    我们常常用下面的代码获得Logger,相信通过上面的讲解,你已经知道怎么获取的了。其实就是根据Class的完全限定名,去HashTable中获取,如果不存在则创建,然后更新parent以及child.

    
    private static Logger logger = Logger.getLogger(Test.Class);
    
    

    参考

    [1]http://blog.csdn.net/u011794238/article/details/50742658

    [2]http://blog.csdn.net/wanglz666/article/details/43195149

  • 相关阅读:
    HDU 3951 (博弈) Coin Game
    HDU 3863 (博弈) No Gambling
    HDU 3544 (不平等博弈) Alice's Game
    POJ 3225 (线段树 区间更新) Help with Intervals
    POJ 2528 (线段树 离散化) Mayor's posters
    POJ 3468 (线段树 区间增减) A Simple Problem with Integers
    HDU 1698 (线段树 区间更新) Just a Hook
    POJ (线段树) Who Gets the Most Candies?
    POJ 2828 (线段树 单点更新) Buy Tickets
    HDU 2795 (线段树 单点更新) Billboard
  • 原文地址:https://www.cnblogs.com/beginmind/p/6067209.html
Copyright © 2011-2022 走看看