springboot2.7.x默认使用的是logback-1.2.x及以下版本,而如果使用logback-1.3.x及以上版本,启动就会报错。主要原因是springboot2.7.x会依赖logback-classic-1.2.x中的类org.slf4j.impl.staticloggerbinder,而logback-classic-1.3.x中已经将此类删除了。
一、报错原因分析
下面通过分析源代码查找报错原因,组件版本如下:
spring-boot-2.7.18
logback-classic-1.2.11
springboot启动时会调用方法loggingapplicationlistener.onapplicationenvironmentpreparedevent,其中会获取到loggingsystem的实例:

而生成loggingsystem实例的方法是loggingsystem.get

其中system_property=org.springframework.boot.logging.loggingsystem
若system_property的值是loggingsystem的实现类的类名,比如:org.springframework.boot.logging.logback.logbackloggingsystem,则会创建这个类的实例;
若system_property的值是none,则生成nooploggingsystem;
否则,springboot会在类路径中自己去查找有哪些日志组件,然后实例化。
在onapplicationenvironmentpreparedevent中获取到loggingsystem实例后,就会调用initialize方法:

在其中会调用initializesystem方法

其中config_property=logging.config,也就是从环境变量logging.config中获取logback的配置文件,然后使用logbackloggingsystem.initialize对logback进行初始化

查看getloggercontext()的源代码

可以看到staticloggerbinder是在这个地方被用到了。
二、解决方案
通过分析上面的源代码就可以知道,如果想让springboot2.7.x使用logback-classic-1.3.x及以上版本,则需要先将环境变量org.springframework.boot.logging.loggingsystem的值设置成none,也就是不让springboot帮忙初始化logback,改由应用自己初始化logback。
另外,logback-classic升级到1.3.x以上版本,slf4j也要升级到1.8.x及以上版本,原因可以参考《java:logback-classic与slf4j版本对应关系》。
最后,如果logback配置文件的路径以前是通过环境变量logging.config配置的,则需要将logback配置文件的路径通过环境变量logback.configurationfile进行配置:

其中config_file_property=logback.configurationfile
上述源代码属于logback-classic组件,版本如下:
logback-classic-1.3.15
另外,以上给出的解决方案logback的官方网站上也有,大家可以参考一下:

地址:https://logback.qos.ch/download.html
三、进一步说明
如果应用是在servlet3.0以上容器部署时,logback会由ch.qos.logback.servlet.logbackservletcontainerinitializer初始化,而springboot由org.springframework.web.springservletcontainerinitializer初始化,这2个类都实现了javax.servlet.servletcontainerinitializer接口。一般servlet容器会先执行logbackservletcontainerinitializer,这样就会把logback初始化完成,所以logback一般不是在执行springservletcontainerinitializer的过程中初始化的。
这就解释了为什么只能通过环境变量logback.configurationfile配置logback.xml的路径,因为想通过spring的配置设置logback.xml的路径已经错过机会了。
到此这篇关于springboot2.7.x将logback升级到1.3.x以上版本的全过程解析的文章就介绍到这了,更多相关springboot将logback升级到1.3.x版本内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论