配置Maven以使用SLF4J

我主要写文章的原因有两个:了解我的新知识或记录我经常必须向他人解释的内容。 本文绝对属于第二类:为了庆祝新的1.0.0版本的Logback ,我决定一劳永逸地写下如何在Maven中正确使用SLF4J,因为似乎不乏有关它的问题。

基本

SLF4J的基础是具有两个单独的组件,一个API和一个实现。 这意味着您的代码应仅依赖于API,因此可以在您方便时更改实现。 请记住,通过引入接口将代码与实现脱钩应该是您的首要考虑:在库级别,这是API的作用。

在您的POM中可以很容易地做到这一点:

<project...>
    <dependencies>
        <dependency>
            <groupId> org.slf4j </groupId>
            <artifactId> slf4j-api </artifactId>
            <version> 1.6.4 </version>
        </dependency>
        <dependency>
            <groupId> ch.qos.logback </groupId>
            <artifactId> logback-classic </artifactId>
            <scope> runtime </scope>
            <version> 1.0.0 </version>
        </dependency>
    <dependencies>
</project>

runtime范围使我们无法在编码时使用Logback的实现类,从而实现了解耦。

如果您正在为项目使用父POM(因为有模块),则不必说上述依赖项应位于dependencyManagement部分下。

桥接

由于仅具有日志记录功能的应用程序受到限制,因此很可能我们需要其他依赖项。 当然,其中一些依赖项可能会使用其他日志记录框架,例如Commons LoggingLog4J

例如,Spring使用Commons Logging:因此,我们的应用程序生成的日志将使用logback,而Spring生成的日志将使用Commons Logging。 该策略需要两个非常不直观的不同配置文件(以及两者的知识)。 而且,当在两个不同的源上读取两个流时,这将是不必要的。 请注意,可以通过使用除文件之外的日志记录目标来缓解这种情况(我尚未见过)。

幸运的是,SLF4J提供了桥接组件,使我们可以将第三方API调用直接连接到SLF4J。 对于Spring,这意味着删除对Commons Logging的所有依赖关系,并用对Commons Logging to SLF4桥的单个依赖关系替换它们。

<project...>
    <dependencies>
        <dependency>
            <groupId> org.springframework </groupId>
            <artifactId> spring-core </artifactId>
            <version> 3.0.0 </version>
            <exclusions>
                <exclusion>
                    <groupId> commons-logging </groupId>
                    <artifactId> commons-logging </artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId> org.springframework </groupId>
            <artifactId> spring-beans </artifactId>
            <version> 3.0.0 </version>
            <exclusions>
                <exclusion>
                    <groupId> commons-logging </groupId>
                    <artifactId> commons-logging </artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId> org.springframework </groupId>
            <artifactId> spring-context </artifactId>
            <version> 3.0.0 </version>
            <exclusions>
                <exclusion>
                    <groupId> commons-logging </groupId>
                    <artifactId> commons-logging </artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId> org.slf4j </groupId>
            <artifactId> jcl-over-slf4j </artifactId>
            <version> 1.6.2 </version>
        </dependency>
    <dependencies>
</project>

像以上部分一样,您最好使用

尽管这些知识不是必需的,但是请知道由于API和实现都是在commons-logging.jar中一起打包的,因此jcl-over-slf4.jar桥完全替代了Commons Logging提供的API类。 这意味着您不应在类路径中同时包含两个JAR!

故障排除

记住高地人的规则:“只能有一个”。 在这种情况下,由于SLF4J使用Java 服务提供程序 ,因此在类路径上只能使用一种实现。 如果是这种情况,SLF4J将显示“在类路径上找到多个绑定”警告,并使用它找到的第一个(类路径上的第一个)。 由于类路径是由Maven排序的,因此很少有可能是我们想要的东西。 因此,请注意不要将slf4j-simple与logback一起放在测试范围内,或者准备面对不确定的副作用。

翻译自: https://blog.frankel.ch/configuring-maven-to-use-slf4j/