问题描述
从我在示例spring pom.xml文件中看到的是,它们为slf4j和log4j添加了一些条目,以及在春季应用程序中使用log4j时,它将由slf4j库包装.
.有人可以向我解释这是如何神奇的吗?
推荐答案
Spring仍然使用commons-logging用于所有内部日志记录(向后兼容). 如果您想使用其他一些记录框架(log4j),则需要 bridge 从commons logging进行调用到您选择的框架.否则,您将必须维护多个记录配置.
slf4j充当各种日志记录框架(jul,log4j,jcl,logback)的简单外墙,并允许您在部署时间插入所需的日志记录框架.
而不是使用第三方框架实施的记录框架实现,您提供的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>
这与弹簧容器或依赖注入无关,它是纯classpath,classloader的东西...
请参阅 -logging-and-slf4j">以下链接以获取更多详细信息.
其他推荐答案
slf4j是一种记录API,无需做任何事情,只有一堆接口. log4j是一个登录系统,带有具体类.有一个slf4j-log4j库,它使用log4j作为SLF4J API的后端.
某些项目明确取决于log4j,他们称之为具体类.因此,您不能仅使用SLF4J API明智地制作其他后端(例如,登录或J.U.L或Apache Commons或其他任何).
有一个技巧用模拟实现(桥梁)代替log4j类(桥梁)只需将所有调用重定向到SL4J即可.在Maven中,您只是声明具有很高版本号的依赖项,并且该模拟被认为是超现代log4j库.
其他推荐答案
尝试添加:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
问题描述
From what I have seen in example spring pom.xml files is that they add a few entries for slf4j and log4j and somehow when you use log4j in your spring application it will be wrapped by slf4j library.
Can someone explain to me how this magically happens?
推荐答案
Spring still uses commons-logging for all the internal logging (backwards compatibility). If you wish to use some other logging framework (log4j) then you need to bridge the calls from commons logging to your framework of choice. Otherwise you will have to maintain multiple logging configurations.
slf4j acts as a simple facade for various logging frameworks (jul, log4j, jcl, logback) and allows you to plug in the desired logging framework at deployment time.
Instead of using the logging framework implementation that is imposed by the third party framework you provide the slf4j's bridge implementation that acts like the real thing but really just forwards the logging calls to slf4j or its concrete binding.
Logging section of Maven pom.xml usually looks like this:
<!-- 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>
This has nothing to do with the Spring container nor dependency injection, it is pure classpath, classloader stuff...
Please see the following links for further details.
其他推荐答案
slf4j is a logging API, which doesn't do anything, just bunch of interfaces. log4j is a logging system, with concrete classes. there is a slf4j-log4j library which uses log4j as a backend for the slf4j API.
Some projects explicitly depend on log4j, they call concrete classes. So, you cannot use another backend (e.g. logback or j.u.l or apache commons or whatever) for your project which you wisely made using the slf4j API only.
There is a trick to substitute log4j classes by a mock implementation (the bridge) which just simply redirects all calls to the sl4j. In maven you just declare a dependency with very high version number and this mock considered as ultra-modern log4j library.
其他推荐答案
try with adding :
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>