SpringBoot踩坑之整合Redis

SpringBoot与Redis整合

今天在做spring boot和redis整合时,出现了JedisConnectionFactory无法实现自动注入的错误:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.connection.jedis.JedisConnectionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {
     @org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1509)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584)
	... 81 more

附上我引入的redis相关依赖:

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
	<groupId>redis.clientsgroupId>
	<artifactId>jedisartifactId>
dependency>

application.yml文件的相关配置:

spring:
  redis:
    database: 1
    host: 127.0.0.1
    password:
    port: 6379
    timeout: 10000 #毫秒
    jedis:
      pool:
        max-active: 8 #连接池最大连接数
        max-idle: 8 #连接池最大空闲连接
        max-wait: -1 #连接池最大阻塞等待时间,负值表示无限制
        min-idle: 0 #连接池最小空闲连接

还有Redis配置类的代码:

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
     

    @Autowired
    private JedisConnectionFactory jedisConnectionFactory;

    /**
     * 主键 key生成策略
     */
//    @Override
//    public KeyGenerator keyGenerator() {
     
//        return super.keyGenerator();
//    }

    /**
     * 缓存管理器
     */
    @Bean
    public CacheManager cacheManager(JedisConnectionFactory jedisConnectionFactory) {
     
        return RedisCacheManager.create(jedisConnectionFactory);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
     
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        setSerializer(redisTemplate);
        return redisTemplate;
    }

    /**
     * 设置序列化方式
     */
    private void setSerializer(RedisTemplate redisTemplate) {
     

        // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        //该方法在使用redisTemplate之前执行,完成初始化
        redisTemplate.afterPropertiesSet();
    }
}

最后是我的测试代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class testRedis {
     

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //存入字符串
    @Test
    public void putString() {
     
        redisTemplate.opsForValue().set("dk", "123");
        redisTemplate.opsForValue().set("dk", "999", 100, TimeUnit.SECONDS);
    }
}

在经过一番网上的搜索和查阅spring boot相关资料后,发现原来我们在引入spring-boot-starter-redis依赖的时候,它自动帮我们引入了lettuce的依赖:
SpringBoot踩坑之整合Redis_第1张图片
这个lettuce取代了jedis作为redis的驱动,如果我们仍然要用jedis的话,就必须要先排除lettuce的依赖包,再加入jedis的依赖包,具体如下:

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-data-redisartifactId>
	<exclusions>
		<exclusion>
			<artifactId>lettuce-coreartifactId>
			<groupId>io.lettucegroupId>
		exclusion>
	exclusions>
dependency>
<dependency>
	<groupId>redis.clientsgroupId>
	<artifactId>jedisartifactId>
dependency>

最后再次测试,运行顺利,问题解决.

那么这个Lettuce到底是什么呢?

Lettuce 是一个可伸缩的线程安全的 Redis 客户端,支持同步、异步和响应式模式。多个线程可以共享一个连接实例,而不必担心多线程并发问题。它基于优秀 Netty NIO 框架构建,支持 Redis 的高级功能,如 Sentinel,集群,流水线,自动重新连接和 Redis 数据模型.
Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接.
Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问。

你可能感兴趣的:(java,redis,java)