Java日志学习二:Apache Commons Logging (JCL)源码

一.Apache Commons Logging

     http://blog.csdn.net/wwlwxgwenwen/article/details/50090965里提到了commons-logging的工作方式,本文将看下代码怎么实现这一工作方式。

 

二.Apache Commons Logging类结构

     就这么简单,一个接口包,一个实现包。

 

三.类说明

  1. Log:A simple logging interface abstracting logging APIs,和JDBC API是一个性质的东西
  2. Level。对六种日志级别的操作,官网建议我们这样用:
    http://commons.apache.org/proper/commons-logging/guide.html 写道
    It is important to ensure that log message are appropriate in content and severity. The following guidelines are suggested: 
    fatal - Severe errors that cause premature termination. Expect these to be immediately visible on a status console. See also Internationalization. 
    error - Other runtime errors or unexpected conditions. Expect these to be immediately visible on a status console. See also Internationalization. 
    warn - Use of deprecated APIs, poor use of API, 'almost' errors, other runtime situations that are undesirable or unexpected, but not necessarily "wrong". Expect these to be immediately visible on a status console. See also Internationalization. 
    info - Interesting runtime events (startup/shutdown). Expect these to be immediately visible on a console, so be conservative and keep to a minimum. See also Internationalization. 
    debug - detailed information on the flow through the system. Expect these to be written to logs only. 
    trace - more detailed information. Expect these to be written to logs only.
     
  3. LogFactory:抽闲类,获得Log类。 getFactory()先从缓存里取LogFactory,取不到再去找,然后放进缓存。其中找的这段代码如下
    Java代码   收藏代码
    1. public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory"  
    2. protected static final String SERVICE_ID = "META-INF/services/org.apache.commons.logging.LogFactory"  
    3. public static final String FACTORY_PROPERTIES = "commons-logging.properties"  
    4. public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.LogFactoryImpl"  
    5.   
    6. public static LogFactory getFactory() throws LogConfigurationException {  
    7.     //1.系统环境变量里是否定义了LogFactory实现类,System.getProperty(FACTORY_PROPERTY)  
    8.     //2.利用JDK1.3 开始提供的service 发现机制,会扫描classpah 下的SERVICE_ID文件,若找到则装载里面的配置,使用里面的配置  
    9.     //3.Classpath下有FACTORY_PROPERTIES文件的话,看此properties里有无定义FACTORY_PROPERTY  
    10.     //4.如果123找不到LogFactory实现类,使用FACTORY_DEFAULT  
    11. }  
     
    Java代码   收藏代码
    1.  public abstract Log getInstance(String name)  
    2.         throws LogConfigurationException;  
    3. public abstract Log getInstance(Class clazz)  
    4.         throws LogConfigurationException;  
    5.   
    6. public static Log getLog(String name)  
    7.         throws LogConfigurationException {  
    8.         return (getFactory().getInstance(name));  
    9.     }  
    10.   
    11. public static Log getLog(Class clazz)  
    12.         throws LogConfigurationException {  
    13.         return (getFactory().getInstance(clazz));  
    14.     }  
      
  4. LogFactoryImpl,实现LogFactory,真正产生Log类的地方。首先从缓存里取Log,取不到就按照http://blog.csdn.net/wwlwxgwenwen/article/details/50090965 中的顺序加载Log类。(i<classesToDiscover.length) && (result == null)就是这里。
    Java代码   收藏代码
    1. public Log getInstance(Class clazz) throws LogConfigurationException {  
    2.         return (getInstance(clazz.getName()));  
    3.     }  
    4.   
    5. public Log getInstance(String name) throws LogConfigurationException {  
    6.         Log instance = (Log) instances.get(name);  
    7.         if (instance == null) {  
    8.             instance = newInstance(name);  
    9.             instances.put(name, instance);  
    10.         }  
    11.         return (instance);  
    12.     }  
    13.   
    14. private static final String[] classesToDiscover = {  
    15.             "org.apache.commons.logging.impl.Log4JLogger",  
    16.             "org.apache.commons.logging.impl.Jdk14Logger",  
    17.             "org.apache.commons.logging.impl.Jdk13LumberjackLogger",  
    18.             "org.apache.commons.logging.impl.SimpleLog"  
    19.     };  
    20.   
    21.   
    22. private Log discoverLogImplementation(String logCategory)  
    23.     throws LogConfigurationException  
    24.     {  
    25.         // See if the user specified the Log implementation to use  
    26.         //1).首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类;  
    27.   
    28. //2) 如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类;  
    29.   
    30.         String specifiedLogClassName = findUserSpecifiedLogClassName();  
    31.   
    32.         if (specifiedLogClassName != null) {  
    33.                         result = createLogFromClass(specifiedLogClassName,  
    34.                                         logCategory,  
    35.                                         true);  
    36.             return result;  
    37.         }  
    38.         //3) 否则,查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;  
    39.   
    40. //4) 否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类);  
    41.   
    42. //5) 否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog;  
    43.   
    44.               for(int i=0; (i<classesToDiscover.length) && (result == null); ++i) {  
    45.             result = createLogFromClass(classesToDiscover[i], logCategory, true);  
    46.         }  
    47.           
    48.                 return result;   
    49.   
    50. createLogFromClass方法使用Class.forName(logAdapterClassName, true, currentCL),看classpath下是否有此logAdapterClassName   
  5. Log4JLogger:包装了org.apache.log4j.Logger。
  6. Jdk14Logger:包装了JDK1.4的java.util.logging.Logger。
  7. Jdk13LumberjackLogger:包装了JDK1.3及以前版本的java.util.logging.Logger。
  8. SimpleLog:自己实现的一个简单日志。
  9. NoOpLog:不记录日志,都是空方法。

 

四.Log实现类

 

 

五.commons-logging-api.jar

 

  1. 关于commons-logging-api.jar和commong-logging.jar的差别可以参考http://commons.apache.org/proper/commons-logging/guide.html
  2. commons-logging-api.jar it does not include the wrapper Log implementations that require additional libraries such as Log4jAvalon and Lumberjack。必然的commons-logging.jar依赖log4j,而commons-logging-api.jar不依赖任何包。
  3. commons-logging.jar 和 log4j一起,LogFactory.getLog(X)得到的毫无疑问是org.apache.commons.logging.impl.Log4JLogger。
  4. commons-logging-api.jar 和 log4j一起,得到的是org.apache.commons.logging.impl.Jdk14Logger。为什么?commons-logging-api.jar和commons-logging.jar的LogFactoryImpl classesToDiscover都是一模一样的,但commons-logging-api.jar里根本没有Log4JLogger这个类,肯定加载不到,最终使用JDK自身的日志实现类,由Jdk14Logger包装。
  5. 总的来说,你想使用commons-logging和Log4j(或者Avalon Lumberjack),请使用commons-logging.jar 和 log4j。如果你只是想使用commons-logging做一个门面,其它日志做实现,如slf4j,请使用commons-logging-api.jar和slf4j相关jar。

六.总结

  1. LogFactory实现类的查找和Log实现类的查找是两回事。但它们均可以在commons-logging.properties里定义。
  2. 合理采用commons-logging-api.jar和commons-logging.jar,首选commons-logging.jar肯定不会出问题,如果追求代码的干净请合理使用commons-logging-api.jar。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值