读commons-logging源码有感

转载请注明出处http://chillwarmoon.iteye.com
昨天读了一下commons-logging和log4j的部分源码,收获不少。使用日志时,为什么要两个包全部包含到程序中,这两个包之间的关系如何,是怎么样关联起来的?当我们使用日志时为何只依赖于commons-logging所定义的接口,这些接口与log4j是什么关系?两个日志的配置文件在配置时是否有冲突?在分析完代码之后,这些问题迎刃而解。
一、对commons-logging源码分析
在程序中使用日志时,经常将两个包放到程序的classpath目录下,在程序中调用LogFactory.getLog("XXX"),返回的是Log对象,无论是LogFactory,还是Log,都与log4j无关,但是在classpath中,我们需要配置log4j.properties,其中规定了一些log4j的使用属性。
1.首先从LogFactory.getLog("XXX")入手进行分析。在LogFactory第一次使用时调用静态块,初始化属性thisClassLoader为加载LogFactory的classLoader。在方法getLog(String arg)中,调用getFactory().getInstance(name)。
2.getFactory()
(1)得到当前线程的contextClassLoader,以contextClassLoader为关键字查找缓存中是否有相应的factory存在,如果有,则返回该factory;
(2)从contextClassLoader或者systemClassLoader中得到资源commons-logging.properties,若该配置文件中的use_tccl属性为false,则baseContextClassLoader指定为thisClassLoader,否则为contextClassLoader;
(3)建立factory
若通过System.setProperty得到以org.apache.commons.logging.LogFactory为key的值,则以该值为类名字来newFactory
若通过contextClassLoader找到资源META-INF/services/org.apache.commons.logging.LogFactory,则以资源中规定的类名字来newFactory
若通过commons-logging.properties得到以org.apache.commons.logging.LogFactory为key的值,则以该值为类名字来newFactory
默认以类LogFactoryImpl来newFactory
(4)以contextClassLoader来缓存建立的factory
通过分析容易知道,这里是以默认的方式来建立的factory并缓存起来的。即factory对象是通过实例化LogFactoryImpl来建立的。
3.getInstance():
(1)以name为关键字查看缓存是否有Log对象存在,如果有则返回;
(2)发现Log的实现方式:
若在commons-logging.properties得到以org.apache.commons.logging.Log为key的值,则以该值为类名字来createLogFromClass
依次以Log4JLogger、Jdk14Logger、Jdk13LumberjackLogger、SimpleLog为类名字来createLogFromClass,
如果建立成功则返回该Log实现,注意这里的实现是commons-logging中的实现。
(3)以name为参数,调用得到的Log实现的构造函数,返回Log对象。
二、关键点
1.如何createLogFromClass
(1)首先得到的是baseClassLoader。若useTCCL为false,则为thisClassLoader;若没有指定该值,则选择TCCL和TCL中的一个Lowest作为baseClassLoader,例如:如果TCCL是TCL的父classLoader,则选择TCL。一般而言,Lowest的ClassLoader为TCCL。
(2)若baseClassLoader不为空,则利用baseClassLoader来找到资源Log4JLogger.class,否则利用systemClassLoader找到资源Log4JLogger.class。并用该classLoader加载该Log类。
2.与log4j的联系
由baseClassLoader加载的Log类,是commons-logging中的类,在Log4JLogger中存在有对log4j中的Logger类的引用,因此在Log4JLogger构造函数中对Logger属性进行了初始化,以后的Log.debug,Log.info等方法完全是委派到log4j中的logger属性来执行的。
因此在程序中,我们只看到commons-logging而并没有见到log4j的API。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值