如何使用springboot动态连接指定地址的redis?

我有一个需求是根据请求参数连接不同地址的redis
所以我想写一个函数动态获取redisTemplate,传入指定的redis配置参数,以便连接不同的redis,这个函数类似这样:

public static RedisTemplate<Object, Object> getRedisTemplate(RedisConnectInfo info) {
          // redisStandaloneConfiguration
        RedisStandaloneConfiguration redisStandaloneConfiguration = redisStandaloneConfigurationBuild(info);
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        // 序列化方式
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setConnectionFactory(new LettuceConnectionFactory(
                redisStandaloneConfiguration,
                LettuceClientConfiguration.builder().build()
        ));
        // redisTemplate.setConnectionFactory(new JedisConnectionFactory(redisStandaloneConfiguration));
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

// RedisConfigInfo是一个包含redis地址密码等信息的简单pojo
public static RedisStandaloneConfiguration redisStandaloneConfigurationBuild(RedisConfigInfo info) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(info.getHost());
        redisStandaloneConfiguration.setDatabase(info.getDbIndex());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(info.getPassword()));
        redisStandaloneConfiguration.setPort(info.getPort());
        return redisStandaloneConfiguration;
}

我在测试中这样使用:

@Test
public void testRedisTemplateSet() {
  RedisTemplate<Object, Object> redisTemplate = CacheUtils.getRedisTemplate(new         RedisConfigInfo("127.0.0.1", "password", 6379));
  redisTemplate.opsForValue().set("foo", "bar");
}

但无论我使用LettuceConnectionFactory还是JedisConnectionFactory作为RedisConnectionFactory的实现,最后都得到类似(如果是JedisConnectionFactory 则报JedisConnectionFactory was not initialized)的这样一个错误:

java.lang.IllegalStateException: LettuceConnectionFactory was not initialized through afterPropertiesSet()

我想知道我这样写是否正确,还有如何解决这个报错,谢谢

阅读 4.3k
2 个回答

自己实现与redis连接就行了 不需要使用redisTemplate

这个不光要考虑创建 还涉及缓存创建的连接 不能无限制的创建下去

    private RedisTemplate<Object, Object> createRedisTemplate() {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        if (this.defaultRedisSerializer != null) {
            redisTemplate.setDefaultSerializer(this.defaultRedisSerializer);
        }
        redisTemplate.setConnectionFactory(this.redisConnectionFactory);
        redisTemplate.setBeanClassLoader(this.classLoader);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

这是 spring 生成 RedisTemplate 的方法,地址在 org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration

ConnectionFactory 可以自己去生成 JedisConnectionFactory

不同的客户端对应不同的 ConnectionFactory,对应不同的 RedisTemplate

你可以提前就把多个 redis 对应的 RedisTemplate 生成好保存起来,也可以根据参数到内存中查找,如果对应的 RedisTemplate 不存在就找配置文件生成。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏