背景
一个爬虫项目遇到了反爬,需要验证下代理 IP 能否解决反爬问题,所以在项目中引入了 spring-boot-starter-data-redis
用 RedisTemplate
来存储爬来的代理 IP。项目的日志框架是 slf4j-api
,运行正常。
但是引入这个新依赖配置后,启动报错:
Caused by: java.lang.IllegalArgumentException:
LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
日志框架变成了 logback
了,本文来梳理一下 SpringBoot 引入 log4j 日志框架的流程,出现该问题的原因及解决办法。
log4j 配置
项目使用 log4j ,那么需要引入 slf4j-api
并且将 SpringBoot 启动模块依赖的日志包剔除,pom.xml 配置文件如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
引入目标日志包:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
spring-boot-starter-data-redis
这个依赖包引入之后,我们可以看到它引入的其他包结构为:
找到症结:它依赖了 logback 的日志框架,从而覆盖了项目原有的日志配置。
解决办法
新引入的依赖包包含了默认日志框架,也需要排除:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!--排除默认的日志依赖包,否则启动应用报错-->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
启示录
说来惭愧,出现问题第一反应竟然是百度异常信息,看了一些搜索结果都不是问题原因,于是放了一夜。今天觉得从日志配置的源头来分析问题,找到日志配置的关键是排除starter
中的日志包。
去掉新依赖包,工程正常启动;再加上依赖,展开相关依赖结构果然发现了默认日志包,添加排除配置后,问题解决。