在Maven中使用日志系统
- 由于JCL-over-SLF4J和原来的JCL具有完全相同的API,因此两者是不能共存的。
- Logback和slf4j-log4j12也不能并存,否则SLF4J会迷惑并产生不确定的结果
组装完整的日志系统将涉及如下部件:
日志系统的组成
类别 | 组件名称 | 说明 |
日志框架 | SLF4J | Webx框架以及所有新应用,直接依赖于SLF4J。 |
JCL | Spring框架、许多以前的老应用,都使用JCL来输出日志。 好在SLF4J提供了一个“桥接”包:JCL-over-SLF4J,它重写了JCL的API,并将所有日志输出转向SLF4J。这样就避免了两套日志框架并存的问题。 | |
日志系统 | Logback | Webx推荐使用logback来取代log4j。 Logback可直接被SLF4J识别并使用。 |
Log4j | 由于客观原因,有些系统暂时不能升级到Logback。 好在SLF4J仍然支持Log4j。Log4j需要一个适配器slf4j-log4j12才能被SLF4J识别并使用。 |
在Maven中配置logback作为日志系统
配置pom.xml以使用logback
1 <dependencies>
2 <dependency>
3 <groupId>org.slf4j</groupId>
4 <artifactId>slf4j-api</artifactId>
5 </dependency>
6 <dependency>
7 <groupId>org.slf4j</groupId>
8 <artifactId>jcl-over-slf4j</artifactId>
9 </dependency>
10 <dependency>
11 <groupId>ch.qos.logback</groupId>
12 <artifactId>logback-classic</artifactId>
13 </dependency>
14 </dependencies>
15
16 <dependencyManagement>
17 <dependencies>
18 <dependency>
19 <groupId>org.slf4j</groupId>
20 <artifactId>slf4j-api</artifactId>
21 <version>1.7.5</version>
22 </dependency>
23 <dependency>
24 <groupId>org.slf4j</groupId>
25 <artifactId>jcl-over-slf4j</artifactId>
26 <version>1.7.5</version>
27 </dependency>
28 <dependency>
29 <groupId>ch.qos.logback</groupId>
30 <artifactId>logback-classic</artifactId>
31 <version>1.0.13</version>
32 <scope>runtime</scope>
33 </dependency>
34 <dependency>
35 <groupId>commons-logging</groupId>
36 <artifactId>commons-logging</artifactId>
37 <version>1.1.3</version>
38 <scope>provided</scope>
39 </dependency>
40 </dependencies>
41 </dependencyManagement>
把所依赖jar包的版本定义在<dependencyManagement>中,而不是<dependencies>中。因为前者可影响间接依赖,后者只能影响直接依赖。
如果你的项目指定了parent pom,那么建议把<dependencyManagement>放在parent pom中,以便多个子项目共享配置。
将logback日志系统的依赖设定为<scope>runtime</scope>,因为应用程序永远不需要直接调用日志系统,而是通过SLF4J或JCL这样的日志框架来调用它们。
由于和jcl-over-slf4j存在冲突,因此JCL(commons-logging)是必须被排除的。由于maven目前缺少这样一个功能:它不能全局地排除一个jar包依赖,所以建议将commons-logging设置成<scope>provided</scope>,这样在最终的依赖关系中,将不会包含commons-logging包。
将commons-logging设置成<scope>provided</scope>
可以用来排除commons-logging,然而这样做有一个缺点 —— 你无法从单元测试中将commons-logging排除。假如这个影响了你的单元测试的话,请使用另一种方案:
另一种排除commons-logging的方法
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>99.0-does-not-exist</version> </dependency>
“ |
最后,你需要在项目文件夹下面,执行一下命令:“mvn dependency:tree
”,确保没有jar包直接或间接依赖了slf4j-log4j12。如果有的话,你可以用下面的配置来排除掉:
排除间接依赖的slf4j-log4j12
<dependencyManagement>
<dependencies>
<dependency>
<groupId>yourGroupId</groupId>
<artifactId>yourArtifactId</artifactId>
<version>yourVersion</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
事实上,如果有其它的jar包依赖slf4j-log4j12,这本身就是有错误的。因为应用不应该直接依赖于这些包中的API —— 它们只应该依赖于日志框架API。任何应用都应该把下列和日志系统相关的依赖(如:slf4j-log4j12、logback-classic)设置成<scope>runtime</scope>
的。