一. 整合核心包
1.1 门面
Slf4j 基本的日志门面,核心API:org.slf4j:slf4j-api
1.2 核心实现
logback的核心实现层在ch.qos.logback:logback-core中
1.3 适配
logback针对Slf4j的适配层 ch.qos.logback:logback-classic
logback-classic会直接依赖其他两项,且一定是依赖能够支持的最合适版本,所以显式依赖logback-classic即可。
二. 基于依赖兼容
2.1 Slf4j 与JDK
Slf4j 2.0.x有不小的改动,不再主动查找org.slf4j.impl.StaticLoggerBinder,而是改用JDK ServiceLoader(也就是SPI,Service Provider Interface) 的方式来加载实现。这是JDK 8中的特性.
2.2. logback 与slf4j和JDK
2.3 小结
如果使用JDK 8,建议选择Slf4j 2.0 + Logback 1.3;
如果使用JDK 11及以上,建议选择Slf4j 2.0 + Logback 1.5
三. SpringBoot 兼容
Spring Boot通过spring-boot-starter-logging包直接依赖了Logback(然后再间接依赖了 Slf4j),它通过org.springframework.boot.logging.LoggingSystem查找日志接口并自动适配,所以我们使用Spring Boot时一般并不需要关心日志依赖,只管使用即可.
四. 桥接
实际项目中我们依赖的其他二方,三方包中可能使用JCL/Log4j/Log4j2/JUL其他日志框架,为了使其能够正常打印日志,旧需要做好桥接。
org.slf4j:jcl-over-slf4j
org.slf4j:log4j-over-slf4j
org.slf4j:jul-to-slf4j
org.apache.logging.log4j:log4j-to-slf4j log4j2 桥接到Slf4j
五. Maven排包
- 将要排掉的包通过引入一个占位的空包(版本号一般比较特殊,比如999-not-exist),从而达到排包的目的。但这种特殊版本的空包一般在Mvnrepository Central仓库是没有的(各厂的私有仓库一般会有这种包),你可以自己搭建私有仓库并上传这个版本,或者使用Version 99 Does Not Exist [16]也行。这是最完美的方案,无论本地运行还是远程编译都不会有问题。
- 将需要排掉的包使用<scope>provided</scope>标识,这样这个包在编译时会被跳过,从而达到排包的目的,但此包在本地运行时仍会被引入,导致本地运行与远程机器环境差异,不利于调试
- 使用maven-enforcer-plugin[17]插件标识哪些包是要被排掉的,它只是一个校验,实际上你仍然需要在每个引入了错误包的依赖中进行排除