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...