• commons-logging.jar 和 log4j.jar 的关系


      在用springmvc开发项目的时候,在日志管理这一块,我们一般用的都是log4j进行日志管理,但是我们在导入spring相关的jar的时候,都会看到commons-logging.jar包,为什么我们使用log4j的同时还要引入commons-logging.jar包,它们到底是一种什么关系呢?

      接下来我们看看commons-logging中的org.apache.commons.logging.Log的源码

    /*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
    package org.apache.commons.logging;
    
    public abstract interface Log {
        public abstract void debug(Object paramObject);
    
        public abstract void debug(Object paramObject, Throwable paramThrowable);
    
        public abstract void error(Object paramObject);
    
        public abstract void error(Object paramObject, Throwable paramThrowable);
    
        public abstract void fatal(Object paramObject);
    
        public abstract void fatal(Object paramObject, Throwable paramThrowable);
    
        public abstract void info(Object paramObject);
    
        public abstract void info(Object paramObject, Throwable paramThrowable);
    
        public abstract boolean isDebugEnabled();
    
        public abstract boolean isErrorEnabled();
    
        public abstract boolean isFatalEnabled();
    
        public abstract boolean isInfoEnabled();
    
        public abstract boolean isTraceEnabled();
    
        public abstract boolean isWarnEnabled();
    
        public abstract void trace(Object paramObject);
    
        public abstract void trace(Object paramObject, Throwable paramThrowable);
    
        public abstract void warn(Object paramObject);
    
        public abstract void warn(Object paramObject, Throwable paramThrowable);
    }
    View Code

      很显然,commons-logging中j的log类就是一个接口,只要实现了该接j它口,那么它就是一个logger组件,继续看commons-logging下的org.apache.commons.logging.impl.Log4JLogger源码

    /*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
    package org.apache.commons.logging.impl;
    
    import java.io.Serializable;
    import java.lang.reflect.Field;
    import org.apache.commons.logging.Log;
    import org.apache.log4j.Level;
    import org.apache.log4j.Logger;
    import org.apache.log4j.Priority;
    
    public class Log4JLogger implements Log, Serializable {
        private static final long serialVersionUID = 5160705895411730424L;
        private static final String FQCN = Log4JLogger.class.getName();
    
        private volatile transient Logger logger = null;
        private final String name;
        private static final Priority traceLevel;
    
        public Log4JLogger() {
            this.name = null;
        }
    
        public Log4JLogger(String name) {
            this.name = name;
            this.logger = getLogger();
        }
    
        public Log4JLogger(Logger logger) {
            if (logger == null) {
                throw new IllegalArgumentException(
                        "Warning - null logger in constructor; possible log4j misconfiguration.");
            }
    
            this.name = logger.getName();
            this.logger = logger;
        }
    
        public void trace(Object message) {
            getLogger().log(FQCN, traceLevel, message, null);
        }
    
        public void trace(Object message, Throwable t) {
            getLogger().log(FQCN, traceLevel, message, t);
        }
    
        public void debug(Object message) {
            getLogger().log(FQCN, Level.DEBUG, message, null);
        }
    
        public void debug(Object message, Throwable t) {
            getLogger().log(FQCN, Level.DEBUG, message, t);
        }
    
        public void info(Object message) {
            getLogger().log(FQCN, Level.INFO, message, null);
        }
    
        public void info(Object message, Throwable t) {
            getLogger().log(FQCN, Level.INFO, message, t);
        }
    
        public void warn(Object message) {
            getLogger().log(FQCN, Level.WARN, message, null);
        }
    
        public void warn(Object message, Throwable t) {
            getLogger().log(FQCN, Level.WARN, message, t);
        }
    
        public void error(Object message) {
            getLogger().log(FQCN, Level.ERROR, message, null);
        }
    
        public void error(Object message, Throwable t) {
            getLogger().log(FQCN, Level.ERROR, message, t);
        }
    
        public void fatal(Object message) {
            getLogger().log(FQCN, Level.FATAL, message, null);
        }
    
        public void fatal(Object message, Throwable t) {
            getLogger().log(FQCN, Level.FATAL, message, t);
        }
    
        public Logger getLogger() {
            Logger result = this.logger;
            if (result == null) {
                synchronized (this) {
                    result = this.logger;
                    if (result == null) {
                        this.logger = (result = Logger.getLogger(this.name));
                    }
                }
            }
            return result;
        }
    
        public boolean isDebugEnabled() {
            return getLogger().isDebugEnabled();
        }
    
        public boolean isErrorEnabled() {
            return getLogger().isEnabledFor(Level.ERROR);
        }
    
        public boolean isFatalEnabled() {
            return getLogger().isEnabledFor(Level.FATAL);
        }
    
        public boolean isInfoEnabled() {
            return getLogger().isInfoEnabled();
        }
    
        public boolean isTraceEnabled() {
            return getLogger().isEnabledFor(traceLevel);
        }
    
        public boolean isWarnEnabled() {
            return getLogger().isEnabledFor(Level.WARN);
        }
    
        static {
            if (!(Priority.class.isAssignableFrom(Level.class))) {
                throw new InstantiationError("Log4J 1.2 not available");
            }
    
            Priority _traceLevel;
            try {
                _traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(
                        null);
            } catch (Exception ex) {
                _traceLevel = Level.DEBUG;
            }
            traceLevel = _traceLevel;
        }
    }
    View Code
    /*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
    package org.apache.commons.logging.impl;
    
    import java.io.Serializable;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import org.apache.commons.logging.Log;
    
    public class Jdk14Logger implements Log, Serializable {
        private static final long serialVersionUID = 4784713551416303804L;
        protected static final Level dummyLevel = Level.FINE;
    
        protected transient Logger logger = null;
    
        protected String name = null;
    
        public Jdk14Logger(String name) {
            this.name = name;
            this.logger = getLogger();
        }
    
        protected void log(Level level, String msg, Throwable ex) {
            Logger logger = getLogger();
            if (!(logger.isLoggable(level)))
                return;
            Throwable dummyException = new Throwable();
            StackTraceElement[] locations = dummyException.getStackTrace();
    
            String cname = this.name;
            String method = "unknown";
    
            if ((locations != null) && (locations.length > 2)) {
                StackTraceElement caller = locations[2];
                method = caller.getMethodName();
            }
            if (ex == null)
                logger.logp(level, cname, method, msg);
            else
                logger.logp(level, cname, method, msg, ex);
        }
    
        public void debug(Object message) {
            log(Level.FINE, String.valueOf(message), null);
        }
    
        public void debug(Object message, Throwable exception) {
            log(Level.FINE, String.valueOf(message), exception);
        }
    
        public void error(Object message) {
            log(Level.SEVERE, String.valueOf(message), null);
        }
    
        public void error(Object message, Throwable exception) {
            log(Level.SEVERE, String.valueOf(message), exception);
        }
    
        public void fatal(Object message) {
            log(Level.SEVERE, String.valueOf(message), null);
        }
    
        public void fatal(Object message, Throwable exception) {
            log(Level.SEVERE, String.valueOf(message), exception);
        }
    
        public Logger getLogger() {
            if (this.logger == null) {
                this.logger = Logger.getLogger(this.name);
            }
            return this.logger;
        }
    
        public void info(Object message) {
            log(Level.INFO, String.valueOf(message), null);
        }
    
        public void info(Object message, Throwable exception) {
            log(Level.INFO, String.valueOf(message), exception);
        }
    
        public boolean isDebugEnabled() {
            return getLogger().isLoggable(Level.FINE);
        }
    
        public boolean isErrorEnabled() {
            return getLogger().isLoggable(Level.SEVERE);
        }
    
        public boolean isFatalEnabled() {
            return getLogger().isLoggable(Level.SEVERE);
        }
    
        public boolean isInfoEnabled() {
            return getLogger().isLoggable(Level.INFO);
        }
    
        public boolean isTraceEnabled() {
            return getLogger().isLoggable(Level.FINEST);
        }
    
        public boolean isWarnEnabled() {
            return getLogger().isLoggable(Level.WARNING);
        }
    
        public void trace(Object message) {
            log(Level.FINEST, String.valueOf(message), null);
        }
    
        public void trace(Object message, Throwable exception) {
            log(Level.FINEST, String.valueOf(message), exception);
        }
    
        public void warn(Object message) {
            log(Level.WARNING, String.valueOf(message), null);
        }
    
        public void warn(Object message, Throwable exception) {
            log(Level.WARNING, String.valueOf(message), exception);
        }
    }
    View Code

      我们看到有两个类,一个是Jdk14Logger,另一个是Log4JLogger。到这里我们应该知道,真正记录日志的是Jdk14Logger类和Log4JLogger类。而 commons-logging 把这两个(实际上,在 org.apache.commons.logging.impl 包下,commons-logging 仅仅为我们封装了 log4j 和 sun logger)记录日志的工具重新封装了一遍(Log4JLogger.java 和 Jdk14Logger.java),可以认为 org.apache.commons.logging.Log 是个傀儡,它只是提供了对外的统一接口。因此我们只要能拿到 org.apache.commons.logging.Log,而不用关注到底使用的是 log4j 还是 sun logger。正如我们经常在项目中这样写:

    private static final Log logger = LogFactory.getLog(Run.class);  
    View Code

      既然如此,我们的项目有两个jar包,那么我们用的是log4j 还是 Jdk14Logger呢?我们在配置spring的web.xml文件时,经常会有如下配置:

    <listener>  
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
    </listener>  
    View Code

       终于找到了 org.springframework.util.Log4jConfigurer,这正是 log4j 提供给我们的初始化日志的类。至此,我们终于明白了我们系统的的确确使用的是 log4j 的日志工具。 

      可是问题又来了,org.apache.commons.logging.Log 和 org.apache.log4j.Logger 这两个类,通过包名我们可以发现它们都是 apache 的项目,既然如下,为何要动如此大的动作搞两个东西(指的是 commons-logging 和 log4j)出来呢?事实上,在 sun 开发 logger 前,apache 项目已经开发了功能强大的 log4j 日志工具,并向 sun 推荐将其纳入到 jdk 的一部分,可是 sun 拒绝了 apache 的提议,sun 后来自己开发了一套记录日志的工具。可是现在的开源项目都使用的是 log4j,log4j 已经成了事实上的标准,但由于又有一部分开发者在使用 sun logger,因此 apache 才推出 commons-logging,使得我们不必关注我们正在使用何种日志工具。

  • 相关阅读:
    hashlib模块
    configparser模块
    xml模块和shelve模块
    json与pickle模块
    3/30
    os模块
    sys模块
    shutil模块
    random模块
    2月书单《编码隐匿在计算机软硬件背后的语言》 13-16章
  • 原文地址:https://www.cnblogs.com/Hxinguan/p/8011397.html
Copyright © 2020-2023  润新知