日志框架与门面模式
日志框架
目前的日志框架可以分为两种:一种是jdk自带的,一种是第三方实现的。
第三方的日志框架除了提供具体的日志实现外,也有的会提供自身框架的接口。此外,有些日志框架仅仅提供了一套统一的接口,不包含具体的日志实现,可以通过一些桥接包来调用其他的日志框架。(即日志的门面模式)
jdk自带的日志框架
jdk自带的日志是jdk-logging,简称jul(java.util.logging包的简称)。
Tomcat本身的日志实现是tomcat-juli.jar
,从jar名就可以看出来,它是对jul的实现,内部对jul进行了一定的封装。
jul的配置文件是logging.properties
。下面是jul的一个简单demo,jul的日志级别和第三方的日志框架不太相同:
|
|
第三方的日志框架
常见的有logback、log4j、log4j2这三大日志框架,其中log4j2是log4j 1.x的升级版,因为改动很大,所以作为一个新的日志框架独立使用。
logback的配置文件是logback.xml
,log4j的配置文件是log4j.xml
,log4j2的配置文件是log4j2.xml
。有的日志框架的配置文件也可以是xml以外的文件,比如yaml文件、propertites文件,不过通常会使用xml文件(因人而异)。
日志门面commons-logging
门面模式(也叫外观模式),由于市面上的第三方框架较多,往往一个项目中可能引入多种日志(比如使用了某个第三方的库,该库又使用了与项目不同的日志),为了方便管理,同时也是为了面向接口编程,于是不再直接使用某个具体的日志实现,而是借由统一的日志接口来调用具体的日志实现,这样就可以实现项目与日志的解耦。而在使用统一的日志接口时,项目中只能引入一种具体的日志实现框架(即门面模式的应用,此时项目不能同时混用多种日志实现,如果是第三方库引入的日志实现则没事),否则门面接口无法知道项目具体应该使用哪一种日志实现,会抛异常。
最早的日志门面是Apache的commons-logging(简称为jcl),日志门面的用法即为:使用门面接口的API来打印日志,项目会通过Java的SPI机制来自动找到对应的日志实现来完成打印日志的功能:
|
|
通常在导入门面接口和具体的日志实现两个依赖后,再添加对应日志框架的配置文件即可。在集成不同的日志实现时,有的可能需要引入额外的桥接包,因为并不是所有日志实现直接实现了门面接口,可能存在着其他的接口,此时需要通过额外的桥接包来将两者适配起来,相当于一个适配器,比如在集成log4j2的时候就需要额外引入log4j-jcl
的jar。
可以看到,项目中无需出现具体的日志框架的代码即可完成日志打印,这意味着在切换日志框架时成本很低,完全不需要改动代码,只需要改变具体的日志依赖和对应的配置文件即可。
此外,jcl可以有自身的配置文件commons-logging.properties
,一般不用这个。因为不同的日志框架有各自不同的特性与优势,最好是使用对应的独立的配置文件来实现解耦。
日志门面slf4j
slf4j是Simple Logging Facade for Java,即简单日志门面,是目前较为流行的门面接口,用法和jcl一样,即使用slf4j自身提供的接口来打印日志:
|
|
目前很流行的Lombok框架,可以通过一个简单的@Slf4j
注解来更为简洁方便地来使用Slf4j打印日志:
|
|
无需导包也无需书写Slf4j的接口代码,直接使用log
变量即可打印日志。