前言
昨天自己在重新学习SpringBoot整合Redis时,遇到了一个问题java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig,错误很明显找不到需要的类。下面主要记录一下错误是怎么出线的,并且如何解决。
错误回顾
在SpringBoot 2.0+后,默认的redis client是lettuce而不是一直使用的jedis。此次出现的错误也是因为使用了lettuce出现的。
使用时的配置如下所示:
spring:redis:host: localhostport: 6379password:# 连接超时时间timeout: 10s# springboot默认使用lettucelettuce: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 {@Autowiredprivate RedisTemplate<Object, Object> redisTemplate;@Testpublic 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配置项,这样初始化就执行默认的连接池了。🤔但是好像不配置的话又不符合企业级应用要求,所以还是当一个听话的好孩子吧,这样在之后出错的话就会有人站出来为你说一句: “他还是个孩子啊!!~”
🔚
这次记录就到这里啦~ 献给努力的我们。