SLF4J/JPA/JAX-RS如何找到它们的实现?

Kev*_*vin 6 java logging slf4j

我正在学习Java,我发现有许多标准化的功能:

  • 记录(使用SLF4J)
  • 持久性(使用JPA)
  • REST(使用JAX-RS)
  • SOAP(使用JAX-WS)
  • 等等

让我们看一下Sl4j示例:要正确使用log4j,我们必须导入sl4j api,sl4j/log4j桥和log4j实现.

问题:在我的课堂上,我只与Slf4j API进行通信.

我的应用程序如何知道log4j实现?有人可以解释一下究竟发生了什么吗?

问候

Zak*_*ria 4

OP 提出了一个关于如何在某些不同情况下注入实现的一般问题。

记录

正如许多答案所述,SLF4J给出了接口并log4j-slf4j给出了实现。

当您使用以下语句时:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    ...
    private static final Logger LOG = LoggerFactory.getLogger(FooBarClass.class);
    ...
    LOG.debug("Foobar");
Run Code Online (Sandbox Code Playgroud)

这就是正在发生的事情:

我们尝试从类中声明的方法Logger中获取:getLoggerLoggerFactory

public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == UNINITIALIZED) {
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == UNINITIALIZED) {
                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                    performInitialization();
                }
            }
        }
        switch (INITIALIZATION_STATE) {
        case SUCCESSFUL_INITIALIZATION:
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        }
        ...
    }
Run Code Online (Sandbox Code Playgroud)

所以神奇的事情就发生在这句话上:

return StaticLoggerBinder.getSingleton().getLoggerFactory();
Run Code Online (Sandbox Code Playgroud)

因为类路径知道您实现的原因,所以StaticLoggerBinder实现log4j. 我们可以注意到,log4j提供了自己的实现:

private final ILoggerFactory loggerFactory;
...
private StaticLoggerBinder() {
    loggerFactory = new Log4jLoggerFactory();
}
Run Code Online (Sandbox Code Playgroud)

就是这样!

坚持

对于 JPA/Hibernate 部分,您必须包含hibernate-jpa-apiand hibernate-*(核心、实体管理器等)。

假设您想创建一个EntityManagerFactory

    import javax.persitence.EntityManagerFactory
    import javax.persitence.Persistence;
    ...
    private static EntityManagerFactory EMF = Peristence.createEntityManagerFactory("foobar", null);
Run Code Online (Sandbox Code Playgroud)

至于ListArrayList,由于您导入的 JAR,您的类路径中包含了接口和实现。

来自我们上课EntityManagerFactory地方。我们可以注意到,该方法首先列出了所有提供者,并且对于每个提供者,都会触发一个。这就是事情发生的地方。它提供了一个实现该类方法hibernate-jpa-apiPersistencecreateEntityManagerFactorycreateEntityManagerFactoryhibernateHibernatePersistenceProviderPersistenceProvider

这就是Hibernate注入的方式。