4

经过粗略的检查,似乎 SLF4J 和 Guice(嗯,任何 DI 框架,真的)是一种相互冲突的哲学。SLF4J 采用这种方法“嘿,直到运行时我们才会知道要绑定到哪些类,这没关系。 ”另一方面,Guice 似乎在说“嘿,我们需要在编译时知道究竟我们要绑定哪些类。 ”。

所以我问:是否可以使用 Guice/Spring/任何 DI 框架来配置/注入 SLF4J 绑定?

更重要的是,JavaClassLoader是在运行时使用适当的 Logger/LoggerFactory/etc 真正“注入”SLF4J。对象,所以我不知道如何注入这些 ClassLoaders 以便它们org.slf4j.impl.Logger在运行时返回我想要的:

我问是因为我喜欢 SLF4J 和针对 API 进行日志记录的好处,但也喜欢 DI 的好处。有没有办法使这项工作?提前致谢!

4

3 回答 3

3

我相信这是不可能的(除非你做了一些非常麻烦的事情,比如为你的应用程序创建子类加载器的容器......类似的东西)

SLF4j 具有可替换实现的基本思想是让 binder lib 提供org.slf4j.impl.StaticLoggerBinder,SLF4J API 将通过类加载器查找这个类。因此,如果 classpath 中有超过 1 个 binder,则无法区分org.slf4j.impl.StaticLoggerBinder它们提供的 s。DI 框架不会对此有所帮助,因为 Logging 框架甚至在 DI 发生之前就已初始化。

除非 SLF4J 将来改变它的设计,否则我们无能为力。而且,我怀疑 SLF4J 是否有可能改变它的设计。因为我们无法告诉 DI 容器 Logging 初始化是每个人都依赖的东西。我相信还有更多的原因使它几乎不可能实现。

但是,我怀疑的是,这真的与 DI 有关吗?老实说,我没有看到通过将相应的 JAR 放在类路径中来控制使用哪个日志记录绑定的问题。如果你想在运行时控制它,以编程方式,我认为编写一个小容器来启动你的应用程序是要走的路。但是,它仍然与DI无关。

于 2012-10-26T03:47:48.993 回答
1

解决这个问题的一种相当简单的方法是通过该方法注入一个ILoggerFactory实例。(截至 2012 年 10 月,该方法不存在。) LoggerFactorysetILoggerFactory()setILoggerFactory()

目前 SLF4J 实现的静态绑定机制除了设置ILoggerFactory. 这种方法对你有用吗?

于 2012-10-26T11:28:18.687 回答
1

对于现在发现这一点的任何人:Sangria实现了一个“上下文敏感的活页夹”,对此非常有效;sangria-slf4j具体见sangria-contextual

作者的博客文章中,您可以轻松地设置一个名为 logger factory 的 SLF4J:

public class YourModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new SangriaSlf4jModule());
    }
}

...并且还有一些示例说明如何将新提供程序用于您自己的类型。

于 2016-12-21T16:04:24.407 回答