有没有办法强制 slf4j 使用特定的日志记录提供程序(在我的例子中是 logback)?正如他们的文档中所示:
在类路径上发现多个绑定
SLF4J API 旨在一次与一个且仅一个底层日志框架绑定。如果类路径上存在多个绑定,SLF4J 将发出警告,列出这些绑定的位置。 当类路径上有多个绑定可用时,请选择一个且仅一个您要使用的绑定,并删除其他绑定。例如,如果类路径上有 slf4j->simple-1.6.6.jar 和 slf4j-nop-1.6.6.jar,并且您希望使用 nop(>no-operation)绑定,则删除 slf4j-来自类路径的 simple-1.6.6.jar。如果无法删除多余的绑定,SLF4J 仍将与一个日志框架/实现绑定。从版本 1.6.6 开始,SLF4J 将命名它实际绑定到的框架/实现类。
注意 SLF4J 发出的警告只是一个警告。
就我而言,我有
log4j.jar
、slf4j-log4j12.jar
、log4j-over-slf4j.jar
以及类路径中的所有 logback jar。我知道将 slf4j-log4j12.jar
和 log4j-over-slf4j.jar
放在一起是错误的,但是我的项目非常大,查找和排除 Maven 依赖项并不总是那么简单。在这种情况下,slf4j 甚至没有打印任何警告,因为我们只使用 logback 配置。我花了一天时间才理解这个罐子地狱。
我想要的只是通过 JVM 参数强制 slf4j 使用 logback,这样它就可以打印警告,并且我可以在将来排除 jar。
通常您自己的代码位于类路径的开头。因此,一种方法是创建您自己的 org.slf4j.impl.StaticLoggerBinder 类:
package org.slf4j.impl;
import org.slf4j.ILoggerFactory;
import org.slf4j.spi.LoggerFactoryBinder;
/**
* Force tests to use JDK14 for logging.
*/
@SuppressWarnings("UnusedDeclaration")
public class StaticLoggerBinder implements LoggerFactoryBinder {
private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
public static String REQUESTED_API_VERSION = "1.6";
public static final StaticLoggerBinder getSingleton() {
return SINGLETON;
}
private StaticLoggerBinder() {
}
@Override
public ILoggerFactory getLoggerFactory() {
return new JDK14LoggerFactory();
}
@Override
public String getLoggerFactoryClassStr() {
return "org.slf4j.impl.JDK14LoggerFactory";
}
}
除了清理类路径之外,没有办法强制 SLF4J 与给定的实现绑定。
更新:从 SLF4J 版本 2.0.9 开始,您可以通过“slf4j.provider”系统属性显式指定提供程序类。这绕过了寻找提供者的服务加载器机制,并可能缩短 SLF4J 初始化时间。
我相信,如果您将 logback JAR 放在类路径的开头(或在包含 slf4j impl 的其他 JAR 之前),那么它将被使用。
但是,如果 slf4j 支持指定包含 impl 的 JAR 的 JVM 参数,并覆盖在类路径中查找,那就太好了,这样您就不必对类路径中的 JAR 进行排序以确保您想要的是使用过。