前言
昨天自己在重新学习SpringBoot整合Redis时,遇到了一个问题java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig,错误很明显找不到需要的类。下面主要记录一下错误是怎么出线的,并且如何解决。
错误回顾
在SpringBoot 2.0+后,默认的redis client是lettuce而不是一直使用的jedis。此次出现的错误也是因为使用了lettuce出现的。
使用时的配置如下所示:
spring:
redis:
host: localhost
port: 6379
password:
# 连接超时时间
timeout: 10s
# springboot默认使用lettuce
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
pom使用最小的依赖进行测试验证。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
测试代码,期望结果是控制台显示 123456,表明redis可以正常使用。
@SpringBootTest
public class RedisServiceTest {
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Test
public void testRedis() {
redisTemplate.opsForValue().set("test", "123456");
String abec = (String) redisTemplate.opsForValue().get("test");
System.out.println(abec);
}
}
测试验证结果:

问题原因
跟踪一下源码发现就能轻松的发现问题:
既然使用的事lettuce client,程序中会通过yml配置匹配到LettuceConnectionConfiguration来创建连接池,所以看此类的源码就能得到答案。
/**
* 创建lettuce工厂方法,该方法执行完我们会得到一个RedisConnectionFactory的实现类。 但是目前问题可以清楚的知道,该方法未执行完就出现了报错,所以我们看下面的代码。
*/
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
LettuceConnectionFactory redisConnectionFactory(
ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
ClientResources clientResources) {
LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(builderCustomizers, clientResources,
getProperties().getLettuce().getPool());
return createLettuceConnectionFactory(clientConfig);
}
/**
* 生成lettuce客户端配置
*/
private LettuceClientConfiguration getLettuceClientConfiguration(
ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
ClientResources clientResources, Pool pool) {
LettuceClientConfigurationBuilder builder = createBuilder(pool);
applyProperties(builder);
if (StringUtils.hasText(getProperties().getUrl())) {
customizeConfigurationFromUrl(builder);
}
builder.clientOptions(createClientOptions());
builder.clientResources(clientResources);
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder.build();
}
/**
* lettuce客户端配置构造器
*/
private LettuceClientConfigurationBuilder createBuilder(Pool pool) {
// pool就是我们在yml配置文件中的lettuce.pool配置
// 不为空执行的下面的方法
if (pool == null) {
return LettuceClientConfiguration.builder();
}
return new PoolBuilderFactory().createBuilder(pool);
}
最后执行的方法截图能明显发现错误

😂最后发现就是很简单的问题,很单纯的没有引入commons-pool2的jar包。问题原因就是自己不按照人要求做事,还逼逼赖赖~~ (无能的人儿啊)
解决方法
📢那就如她所愿,增加上新的pom依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
🤣宾狗-------验证通过

当然还有一种方法,就是yml配置文件中不要配置lettuce.pool配置项,这样初始化就执行默认的连接池了。🤔但是好像不配置的话又不符合企业级应用要求,所以还是当一个听话的好孩子吧,这样在之后出错的话就会有人站出来为你说一句: “他还是个孩子啊!!~”
🔚
这次记录就到这里啦~ 献给努力的我们。
作者在重新学习Spring Boot整合Redis时,遇到java.lang.NoClassDefFoundError错误。原因是Spring Boot 2.0+默认redis client为lettuce,而程序未引入commons - pool2的jar包。解决方法一是增加pom依赖,二是yml配置不设lettuce.pool项,但后者不符合企业级要求。
4767

被折叠的 条评论
为什么被折叠?



