背景
一个爬虫项目遇到了反爬,需要验证下代理 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 中的日志包。
去掉新依赖包,工程正常启动;再加上依赖,展开相关依赖结构果然发现了默认日志包,添加排除配置后,问题解决。