日志系统对于各大主流框架或是自己的应用中都是不可或缺的重要组成部分,最近比较关注spring,所以就来分析下spring的日志系统以及spring4和spring5的日志有哪些区别。
对于各种日志技术,可参见我的另一篇文章:https://blog.csdn.net/baomw/article/details/84526738
1,我们先从spring4和5的核心包context包的依赖关系,来看看其涉及的日志依赖包
<spring4依赖关系图>
<spring5依赖关系图>
从上面的依赖关系不难看出,我们spring4所依赖的jar就是我们的jcl,而spring5则依赖了一个叫spring-jcl的包,至于这个spring-jcl到底是什么,是不是就是我们的jcl呢,我们可以通过例子来看看,这个到底是不是我们jcl的实现。
2,我们知道,jcl打印日志有log4j时通过log4j输出日志,没有则通过jul输出日志。
通过上图,可以知道,当加了log4j的时候,通过log4j来输出日志,没加则通过jul来输出日志,可见spring4引入的jcl就是我们原生的jcl(原理参见我的另一篇文章,上有连接。)
可以看到,spring5就算我加了log4j的jar,依然还是通过jul来打印的日志,说明spring-jcl至少不是我们所知道的jcl,那么spring-jcl到底是什么呢?我们可以断点一下,看看拿到的log对象是什么,然后再看看log对象是怎么产生的即可。
2,可以看到,get到的log对象是jul
static {
logApi = LogFactory.LogApi.JUL;
ClassLoader cl = LogFactory.class.getClassLoader();
try {
cl.loadClass("org.apache.logging.log4j.spi.ExtendedLogger");
logApi = LogFactory.LogApi.LOG4J;
} catch (ClassNotFoundException var6) {
try {
cl.loadClass("org.slf4j.spi.LocationAwareLogger");
logApi = LogFactory.LogApi.SLF4J_LAL;
} catch (ClassNotFoundException var5) {
try {
cl.loadClass("org.slf4j.Logger");
logApi = LogFactory.LogApi.SLF4J;
} catch (ClassNotFoundException var4) {
;
}
}
}
}
上图及代码为spring-jcl的logFactory中的两处核心代码:
首先在初始化logFactory的时候,会去执行一个static的代码块,代码也比较简单,主要就是设置我们的logApi,默认是jul,然后依次用log4j2,slf4j-LAL,slf4j去反射判断是否存在对应依赖,如果有则设置logApi为对应值,否则进入catch中继续判断。
然后再getlog的时候,则根据logApi去获取log对象,代码也比较容易了,就是个switch-case,默认是我们的jul来实现。
结合我上篇文章的jcl的实现,发现还是有很大区别的,jcl是封装了一个静态数组,然后依次循环遍历反射,成功则返回对应实现。
原来在spring5的时候,他将jcl给改了,也就是我们的spring-jcl(毕竟大厂,牛逼),然后默认采用了jul来做日志输出了。同时呢还支持slf4j,有着更好的扩展性和兼容性。
好了,关于spring5的日志就说到这里了。谢谢大家