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 ([email protected]) ***/
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);
}

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

/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao ([email protected]) ***/
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;
    }
}

/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao ([email protected]) ***/
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);
    }
}

  我们看到有两个类,一个是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);  

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

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

   终于找到了 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,使得我们不必关注我们正在使用何种日志工具。

时间: 2024-08-25 17:09:22

commons-logging.jar 和 log4j.jar 的关系的相关文章

kettle-engine.jar与 log4j.jar包冲突问题解决办法

java去调用kettle,在lib中引用了kettle-engine.jar, log4j.jar 等包,测试发现有了 kettle-engine.jar这个包,log就不能写到日志文件了,但是可以打印到控制台:到网上查找也有很多朋友遇到类似问题,最后在其官网发现问题说明:http://jira.pentaho.com/browse/PDI-1791: 解决办法:使用压缩工具打开kettle-engine.jar,删除log4j.xml文件即可.

日志组件系列:(2)commons logging和log4j实战

(1).下载组件,引入jar包 (2).配置 (3).使用API 1.下载组件,引入jar包 jar包 下载地址 log4j-1.2.17.jar http://logging.apache.org/log4j/1.2/ commons-logging-1.2.jar http://commons.apache.org/proper/commons-logging/download_logging.cgi 2.配置 在项目的src目录下添加log4j.properties文件,配置如下: log

Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)

Acknowledgments I would like to thank Jacob Kjome for reviewing early drafts of this document. His comments helped to clarify several important points. Jake also keeps reminding us on the log4j-dev mailing list that the child-parent delegation model

Apache Commons logging简介和使用

本章节内容主要来自网络和整理. Apache Commons Logging,又叫做JakartaCommons Logging (JCL),他提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具.它提供给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具.用户被假定已熟悉某种日志实现工具的更高级别的细节.JCL提供的接口,对其它一些日志工具,包括Log4J, Avalon LogKit, and JDK等,进行了

(1)下载Spring framework和commons logging jar包

1.spring framework (1)访问https://repo.spring.io/release/ 并按照/org/springframework/spring目录找下去 (2)也可以直接访问https://repo.spring.io/release/org/springframework/spring/ 在这里,我选择下载了3.2.5.RELEASE版本 2.commons logging jar包 访问地址http://commons.apache.org/proper/com

org.apache.log4j与org.apache.commons.logging这两个包有什么区别

apache common logging是一种log的框架接口,它本身并不实现log记录的功能,而是在运行时动态查找目前存在的日志库,调用相关的日志函数,从而隐藏具体的日志实现log4j是具体的日志实现,真正负责"写"日志的这个功能 common logging本身不是log,你可以把它看做是一个日志的接口而log4j就是日志的实现 使用common logging方式实现日志,主要的原因在于可以忽略底层的日志实现,或者说为以后的日志实现库的更换提供透明界面你可以考虑下,假设从log

java传统web项目添加maven管理jar包,log4j无法正常输出日志

背景 笔者最近在给公司一个老的web项目改造升级,项目使用springmvc+mybatis,由于项目比较久远,没有使用maven管理jar版本,有可能是当时开发任务比较紧迫,不同的同事在不同的时期放入了jar版本各不相同, 看到那么多混乱的jar,真是操心.笔者曾花了大概半个下午的时间,把jar版本整理好,编入pom.xml中,从那个时候,笔者本地项目的jar版本算是交给maven托管了.顿时间心里舒畅了一会儿.心里也计划着和项目组大 家一起统一使用maven管控jar版本混乱的问题.可是事实

log4j.jar 的 简单 使用

log4j.jar 用于记录 java 程序 日志,在项目开发中非常有用 log4j.properties 配置  ( 放在使用到 log4j.jar Logger 的  类 同一个包下) log4j 有五个输出级别.此处用 info 级别举例. 1: 日志  输出到 控制台( 更好的格式化 输出信息到控制台,此处只 输出  日志信息 内容 ,日志信息格式化 还有有很多相应的参数) 1 log4j.rootLogger=INFO,appender1 2 3 # 输出到控制台 4 log4j.ap

java jar包 log4j不能输出解决方法

今天运行一个jar包,jar包中使用了springContext进行加载bean和log4j配置,但是发现不能正常输入日志. 代码中增加 Xxx.class.getResource("/"); 输出classpath,但是输出结果是null 查找后可以手动加载log4j配置文件 PropertyConfigurator.configure("/export/server/runjar/log4j.properties"); 问题解决