LogFactory.getLog之commons_logging.jar源码分析

1. 查找日志工厂类实例。

1.1 log = LogFactory.getLog(Class),    实际是调用getFactory().getInstance()    

     public static Log getLog(Class clazz)
         throws LogConfigurationException {

         return (getFactory().getInstance(clazz));

     }

1.2  getFactory()主要查询LogFactory实现类, 查询步骤如下。

     a. 查找系统环境变量:org.apache.commons.logging.LogFactory (= FACTORY_PROPERTY)  

          String factoryClass = getSystemProperty(FACTORY_PROPERTY, null);

      b. 如果步骤a没有找到,则再次查找文件 "META-INF/services/org.apache.commons.logging.LogFactory" (=SERVICE_ID);

          InputStream is = getResourceAsStream(contextClassLoader,SERVICE_ID);读取第一行

     c. 如果仍然没有找到,则找配置文件"commons-logging.properties" (=FACTORY_PROPERTIES)

         props =  getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES);

         String factoryClass = props.getProperty(FACTORY_PROPERTY);

   

      d. 如果仍然都没有,则使用默认的org.apache.commons.logging.impl.LogFactoryImpl

2  日志类查找

    2.1 以默认的日志工厂类为例: org.apache.commons.logging.impl.LogFactoryImpl.getInstance(Class)

     a .  LogFactoryImpl.newInstance(String class.getName)

      b.   discoverLogImplementation(name);

     c.   查找日志实现类:findUserSpecifiedLogClassName{

         i) 查找commons-logging.properties的org.apache.commons.logging.Log

             String specifiedClass = (String) getAttribute("org.apache.commons.logging.Log");     //

         ii) 没找到,再找系统环境变量

             specifiedClass = getSystemProperty(LOG_PROPERTY, null);

         iii)如果找到了,根据日志实现类名实例化

           result = createLogFromClass(specifiedLogClassName,
                                        logCategory,//    日志调用的原始业务类名
                                        true);

        vi) 如果没找到,则使用默认顺序构造日志实现类,如下图顺序

             private static final String[] classesToDiscover = {
                  “org.apache.commons.logging.impl.Log4JLogger”,
                 "org.apache.commons.logging.impl.Jdk14Logger",
                 "org.apache.commons.logging.impl.Jdk13LumberjackLogger",// 调用
                "org.apache.commons.logging.impl.SimpleLog"
          };

          for(int i=0; (i<classesToDiscover.length) && (result == null); ++i) {
            result = createLogFromClass(classesToDiscover[i], logCategory, true); // 使用默认的日志实现类
         }

      vii) 以org.apache.commons.logging.impl.Log4JLogger为例

              constructor.newInstance({logCategory});相当于调用new Log4JLogger(logCategory)

3.日志打印(以Log4j为例):new Log4JLogger(String logCategory)      //  logCategory为业务逻辑类名

    a.构造体 会 调用getLogger(): 

    b.getLogger()会实例化log4j日志=org.apache.log4j.Logger.getLogger(logCategory)     实际调用Log4j的日志实现类

4.日志显示。  log.debug, 相当于调用 new Log4JLogger(String logCategory).debug(),

   也就是调用 Log4j的debug方法    log4j.log(FQCN, Priority.DEBUG, message, null );


5.总结: 从上述过程可以知道LogFactory.getLog(Class)在不配置任何文件的情况下,默认使用的就是Log4j日志器.

 因此在我们直接想使用Log4j的情况下,可以直接写为: org.apache.log4j.Logger.getLogger(logCategory)  即可。正如上述步骤3的演化过程结果。

        

发布了16 篇原创文章 · 获赞 0 · 访问量 2855

猜你喜欢

转载自blog.csdn.net/peidezhi/article/details/8681577