每次应用升级pom依赖的版本,遇到jar包冲突的问题都与日志有关,而且每次会有各种各样log相关的jar被加载,这些包都是做什么呢?到底是谁跟谁冲突了呢?带着这些疑问,我在网上找了一些相关的资料。
应用中引入的log相关的jar各种各样,很容易发生冲突,这些jar包根据用途分为三种类型:接口门面,日志实现,日志桥接器。
日志实现:
Log4j
Apache 的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务 器、NT的事件记录器、UNIX Syslog守护进程等;用户也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,用户能够更加细致地控制日志的生成过程。这些可以通过一个 配置文件来灵活地进行配置,而不需要修改程序代码
LogBack
Logback 是由log4j创始人设计的又一个开源日记组件。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日记系统如log4j或JDK14 Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日记的功能。
Nop等其它
为了克服多种日志系统并存所带来的混乱,就出现了“日志框架”。日志框架其实就是为了解藕具体应用和具体日志系统而提供的一个接口层,日志框架本身不提供记录日志的功能,它只提供了日志调用的接口。
接口门面:
common-logging
common-logging(JCL)是apache提供的一个通用的日志接口。用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。
动态查找原理:Log 是一个接口声明。LogFactory 的内部会去装载具体的日志系统,并获得实现该Log 接口的实现类。LogFactory 内部装载日志系统的流程如下:
1. 首先,寻找org.apache.commons.logging.LogFactory 属性配置。
2. 否则,利用JDK1.3 开始提供的service 发现机制,会扫描classpah 下的META-INF/services/org.apache.commons.logging.LogFactory文件,若找到则装载里面的配置,使用里面的配置。
3. 否则,从Classpath 里寻找commons-logging.properties ,找到则根据里面的配置加载。
4. 否则,使用默认的配置:如果能找到Log4j 则默认使用log4j 实现,如果没有则使用JDK14Logger 实现,再没有则使用commons-logging 内部提供的SimpleLog 实现。
从上述加载流程来看,只要引入了log4j 并在classpath 配置了log4j.xml ,则commons-logging 就会使log4j 使用正常,而代码里不需要依赖任何log4j 的代码。
slf4j
slf4j全 称为Simple Logging Facade for JAVA,java简单日志门面。类似于Apache Common-Logging,是对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑 定真正的Log库。使用SLF4J时,如果你需要使用某一种日志实现,那么你必须选择正确的SLF4J的jar包的集合(各种桥接包)。
slf4j静态绑定原理:SLF4J 会在编译时会绑定import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的绑定接入。任何一种基于slf4j 的实现都要有一个这个类。如:org.slf4j.slf4j-log4j12-1.5.6: 提供对 log4j 的一种适配实现。注意:如果有任意两个实现slf4j 的包同时出现,那么就可能出现问题。
slf4j版本变更:http://www.slf4j.org/compatibility.html
桥接器:
参考文档:http://www.cnblogs.com/xing901022/p/4149524.html