关于日志JUL,JCL,Log4j,slf4j日志不清楚请参考我的这篇文章https://blog.csdn.net/weixin_37862824/article/details/105691532
一、spring4日志
在spring里面找个会打印日志的类,都会看到这样一串代码
import org.apache.commons.logging.LogFactory;
public class xxx{
protected final Log logger = LogFactory.getLog(getClass());
}
是不是很熟悉,引的是commons-logging.jar下的 org.apache.commons.logging.LogFactory类,也就是JCL输出日志,所以如果我们在pom.xml文件里面引入log4j,那么spring4就会使用log4j来打印日志,如果不引用就会使用JUL来打印。
二、spring5日志
spring依赖的是spring-jcl.jar来打印日志的,为什么会有spring-jcl这种jar,其实是spring自己写的。
import org.apache.commons.logging.LogFactory;
protected final Log logger = LogFactory.getLog(getClass());
public static Log getLog(String name) {
switch(logApi) {
case LOG4J:
return LogFactory.Log4jDelegate.createLog(name);
case SLF4J_LAL:
return LogFactory.Slf4jDelegate.createLocationAwareLog(name);
case SLF4J:
return LogFactory.Slf4jDelegate.createLog(name);
default:
return LogFactory.JavaUtilDelegate.createLog(name);
}
}
虽然引的也是org.apache.commons.logging.LogFactory路径下的类,但要注意这个是spring-jcl.jar的类。
从上面的代码看可以发现通过判断logApi的值,来选择日志类型,那么logApi的值是什么呢,他是怎么被赋值的。
private static LogApi logApi = LogApi.JUL;//默认使用JUL输出
static {
ClassLoader cl = LogFactory.class.getClassLoader();
try {
// Try Log4j 2.x API
cl.loadClass("org.apache.logging.log4j.spi.ExtendedLogger");
logApi = LogApi.LOG4J;
}
catch (ClassNotFoundException ex1) {
try {
// Try SLF4J 1.7 SPI
cl.loadClass("org.slf4j.spi.LocationAwareLogger");
logApi = LogApi.SLF4J_LAL;
}
catch (ClassNotFoundException ex2) {
try {
// Try SLF4J 1.7 API
cl.loadClass("org.slf4j.Logger");
logApi = LogApi.SLF4J;
}
catch (ClassNotFoundException ex3) {
// Keep java.util.logging as default
}
}
}
}
从源码上可以发现,logApi默认值是JUL,上面的静态代码块就是尝试去加载指定的类,如果存在则为logApi赋上对应的类型。
org.apache.logging.log4j.spi.ExtendedLogger //log4j2
org.slf4j.spi.LocationAwareLogger //框架扩展日志的,具体这不是很清楚。
org.slf4j.Logger //酸辣粉
所以spring5里面引入log4j的jar也不会使用log4j打输出日志,如果我们想只想通过log4j来输出日志,而不用log4j2。可以通过酸辣粉(slf4j),和酸辣粉log4j绑定器。