在用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);
}

  很显然,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;
}
}
/*** 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);
}
}

  我们看到有两个类,一个是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,使得我们不必关注我们正在使用何种日志工具。

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

  1. commons-logging 和 log4j 之间的关系

    我们在做项目时,日志的记录是必不可少的一项任务,而我们通常是使用 apache 的 log4j 日志管理工具.然而,在项目中,我们经常会看到两个 jar 包:commons-logging.jar 和 ...

  2. 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 c ...

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

    apache common logging是一种log的框架接口,它本身并不实现log记录的功能,而是在运行时动态查找目前存在的日志库,调用相关的日志函数,从而隐藏具体的日志实现log4j是具体的日志 ...

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

    本文适合1年以上编程基础的开发人员阅读,非技术创新,可作为故障排除实录参考/收藏. 背景 笔者最近在给公司一个老的web项目改造升级,项目使用springmvc+mybatis,由于项目比较久远,没有 ...

  5. 引用log4j.jar包后,出现告警

    问题现象:在引用log4j包后,使用自己导出的jar包,编译测试例代码,在启动浏览器时出现以下告警:log4j:WARN No appenders could be found for logger ...

  6. hibernate中各个jar包的含义和关系

    最基本的Hibernate3.3.2之 JAR包(必要): 包名 位置 用途 hibernate3.jar /hibernate 核心JAR包 antlr.jar /hibernate/lib/req ...

  7. spring 3.0版本以上jar包使用以及依赖关系

    本文转载自:http://blog.csdn.net/huiwenjie168/article/details/8477837 spring.jar是包含有完整发布的单个jar包,spring.jar ...

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

    今天运行一个jar包,jar包中使用了springContext进行加载bean和log4j配置,但是发现不能正常输入日志. 代码中增加 Xxx.class.getResource("/&q ...

  9. spring中各jar功能及jar包之间的依赖关系

    (1) spring-core.jar 这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工 ...

随机推荐

  1. 2018秋季C语言基础课第1次作业

    1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题: 1)大学和高中最大的不同是没有人天天看着你,请看大学理想的师生关系是?有何感想? 答:是  Coach / Trainee (健身教练 / 健身 ...

  2. python之数据类型1

    什么是数据类型及数据类型分类        python中的数据类型 python使用对象模型来存储数据,每一个数据类型都有一个内置的类,每新建一个数据,实际就是在初始化生成一个对象,即所有数据都是对 ...

  3. 2018.09.07 Amount of degrees(数位dp)

    描述 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和. 例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意: 17 = 24+20, ...

  4. 2018.08.21 NOIP模拟 unlock(模拟+找规律)

    unlock 描述 经济危机席卷全球,L国也收到冲击,大量人员失业. 然而,作为L国的风云人物,X找到了自己的新工作.从下周开始,X将成为一个酒店的助理锁匠,当然,他得先向部门领导展示他的开锁能力. ...

  5. 2018.08.16 POJ1183反正切函数的应用(简单数学)

    传送门 代数变形一波. 显然有b,c>a. 那么这样的话可以令b=a+m,c=a+n. 又有a=(bc-1)/(b+c). 带入展开可知m*n=a*a+1. 要让m+n最小只需让m最大,这个结论 ...

  6. json、JSONObject、JSONArray的应用

    type.java package jiekou.duixiang; import java.text.ParseException;import java.text.SimpleDateFormat ...

  7. linux安装mysql~~~mysql5.6.12

    Linux安装mysql服务器 准备: MySQL-client-5.6.12-1.rhel5.i386.rpm MySQL-server-5.6.12-1.rhel5.i386.rpm 首先检查环境 ...

  8. nodejs中如何使用mysql数据库[node-mysql翻译]

    nodejs中如何使用mysql数据库 db-mysql因为node-waf: not found已经不能使用,可以使用mysql代替. 本文主要是[node-mysql]: https://www. ...

  9. python关键的语法

    python关键的语法 1.标准类型分类

  10. sun.jersey使用Jackson转换数据

    差点被com.sun.jersey自身的json转换吓死,遇到List等类型,会把这些也转换为json对象,而不是jsonarray. 被园里的同行拯救了,在web.xml中配置一下就ok. < ...