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

最新文章

  1. 代码性能优化——task
  2. onBackPressed
  3. C++学习笔记28:运行期型式信息
  4. js反序列化时间
  5. DBAccess
  6. 三部曲二(基本算法、动态规划、搜索)-1006-The Same Game
  7. PHP邮件注入攻击技术
  8. SparkContext和RDD
  9. jquery与checkbox的checked属性的问题
  10. Apache OFBiz 学习笔记 之 服务引擎 一
  11. 【转】Hibernate各种主键生成策略与配置详解
  12. wamp安装注意点!
  13. 1数组的join方法
  14. 推荐一个第三方Qt库的集合
  15. input之placeholder与行高的问题
  16. iwlist等工具的移植
  17. Verilog HDL程序设计——基本要素
  18. 笨鸟先飞之ASP.NET MVC系列之过滤器(01过滤器简介)
  19. 使用axios post 提交数据,后台获取不到提交的数据解决方案
  20. H5播放器内置播放视频(兼容绝大多数安卓和ios)

热门文章

  1. Linux下timer延时的使用
  2. Devexpress VCL Build v2014 vol 14.2.7发布
  3. 跳出思维定势,改变交谈习惯zz
  4. 2018.10.19 NOIP训练 游戏问题(分组背包)
  5. java.lang.String cannot be cast to java.util.Date
  6. 20155305乔磊2016-2017-2《Java程序设计》第七周学习总结
  7. JAVA开发常用计算机命令
  8. [译]Autoprefixer:一个以最好的方式处理浏览器前缀的后处理程序
  9. (匹配)Antenna Placement --POJ --3020
  10. 洛谷P2633 Count on a tree(主席树上树)