【问题标题】:How does simply adding slf4j to the pom.xml wrap log4j?如何简单地将 slf4j 添加到 pom.xml 包装 log4j?
【发布时间】:2011-12-29 15:58:18
【问题描述】:

从我在示例 spring pom.xml 文件中看到的是,它们为 slf4j 和 log4j 添加了一些条目,并且不知何故,当您在 spring 应用程序中使用 log4j 时,它将被 slf4j 库包装。

有人可以向我解释这是如何神奇地发生的吗?

【问题讨论】:

    标签: spring log4j slf4j


    【解决方案1】:

    Spring 仍然使用commons-logging 进行所有内部日志记录(向后兼容)。 如果您希望使用其他一些日志框架 (log4j),那么您需要将来自 commons logging 的调用桥接 到您选择的框架。否则,您将不得不维护多个日志记录配置。

    slf4j 充当各种日志框架(jullog4jjcllogback)的简单外观,并允许您在部署时插入所需的日志框架。

    您提供slf4j's 桥接实现,而不是使用第三方框架强加的日志框架实现,它的作用类似于真实事物,但实际上只是将日志调用转发到slf4j 或其具体绑定。

    Maven pom.xml 的日志部分通常如下所示:

    <!-- remove the real commons-logging from classpath -->
    <!-- declare as provided or exclude from spring jars -->
    <dependency>
        <artifactId>commons-logging</artifactId>
        <groupId>commons-logging</groupId>
        <version>1.0</version>
        <scope>provided</scope>
    </dependency>
    
    <!-- add slf4j interfaces to classpath -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.4</version>
        <scope>compile</scope>
    </dependency>
    
    <!-- add commons logging to slf4j bridge to classpath --> 
    <!-- acts as jcl but routes commons-logging calls to slf4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.6.4</version>
        <scope>runtime</scope>
    </dependency>
    
    <!-- add log4j binding to classpath -->
    <!-- routes slf4j calls to log4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.4</version>
        <scope>runtime</scope>
    </dependency>
    
    <!-- add log4j to classpath -->
    <!-- does the logging -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    

    这与Spring容器无关,也与依赖注入无关,它是纯类路径,类加载器的东西......

    更多详情请查看thefollowing链接。

    【讨论】:

    • 虽然这个答案非常好,但其中有一个不准确之处:SLF4J 没有桥接超过公共日志记录,jcl-over-slf4j 依赖项包含重新实现公共日志记录 API。这就是为什么确保公共日志不在您的类路径上至关重要的原因,因为这两个模块使用相同的包名称(作为必要),因此会与每个模块发生灾难性的冲突。 Spring 的“context”模块包含对“spring-core”的依赖,其中包含对“commons-logging”的依赖,这就是为什么在使用 Spring 时必须采取积极措施来防止这种情况发生
    • 在 Spring 中专门排除对 commons-logging 的依赖也更简洁一些,您可以按照this article on Spring's web site 中的说明进行操作,而不是告诉 Maven 您已经在类路径中拥有它(即真的有点小技巧)。
    【解决方案2】:

    slf4j 是一个日志 API,它不做任何事情,只是一堆接口。 log4j 是一个日志系统,具有具体的类。有一个 slf4j-log4j 库,它使用 log4j 作为 slf4j API 的后端。

    一些项目明确依赖 log4j,它们称为具体类。因此,您不能为您明智地仅使用 slf4j API 制作的项目使用其他后端(例如 logback 或 j.u.l 或 apache commons 或其他)。

    a trick 用模拟实现(桥接器)替换 log4j 类,它只是简单地将所有调用重定向到 sl4j。在 maven 中,您只需声明一个版本号非常高的依赖项,这个 mock 被认为是超现代的 log4j 库。

    【讨论】:

    • 所以在运行时它使用依赖注入?还是很困惑抱歉。
    • 不,专家&lt;dependency&gt;。也许我不明白这个问题?你能澄清一下吗?
    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 2020-12-27
    • 2011-07-13
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2018-07-10
    相关资源
    最近更新 更多