为Spring会话和自定义数据使用不同的Redis数据库

时间:2018-03-13 13:46:45

标签: java spring session redis

在我的REST控制器Spring项目中,我想在Redis中存储会话信息以及我在Redis中的自定义信息(无论我需要什么),但是在一个单独的数据库中。

在我的 application.properties 中,我定义了以下内容:

spring.session.store-type=redis
spring.session.redis.namespace=rdrestcore
spring.redis.host=192.168.201.46
spring.redis.port=6379
spring.redis.database=5

com.xyz.redis.host=192.168.201.46
com.xyz.redis.db=0
com.xyz.redis.port=6379
com.xyz.redis.pool.min-idle=5

我还有一个带有以下代码的类(我在某处读到了我需要这个类只是为了让Spring在Redis中管理会话......正如你所看到的,它没有代码):

@Configuration
@EnableRedisHttpSession 
public class SessionConfig extends AbstractHttpSessionApplicationInitializer 
{}

我终于有了这样的redis连接工厂:

@Configuration
@EnableRedisRepositories
public class RdRedisConnectionFactory {
    @Autowired 
    private Environment env;
    @Value("${com.xyz.redis.host}")
    private String redisHost;
    @Value("${com.xyz.redis.db}")
    private Integer redisDb;
    @Value("${com.xyz.redis.port}")
    private Integer redisPort;
    @Value("${com.xyz.redis.pool.min-idle}")
    private Integer redisPoolMinIdle;

    @Bean
    JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();        
        if(redisPoolMinIdle!=null) poolConfig.setMinIdle(redisPoolMinIdle);

        return poolConfig;
    }

    @Bean    
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
        if(redisHost!=null) jedisConFactory.setHostName(redisHost);
        if(redisPort!=null) jedisConFactory.setPort(redisPort);
        if(redisDb!=null) jedisConFactory.setDatabase(redisDb);
        jedisConFactory.setPoolConfig(jedisPoolConfig());
        return jedisConFactory;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        final RedisTemplate< String, Object > template =  new RedisTemplate();
        template.setConnectionFactory( jedisConnectionFactory() );
        template.setKeySerializer( new StringRedisSerializer() );
        template.setHashValueSerializer( new StringRedisSerializer() );
        template.setValueSerializer( new StringRedisSerializer() );
        return template;
    }
}

当我需要Redis读取或写入时,我只需要在需要它的地方自动装配 redisTemplate 并且它可以工作。

现在......问题:Spring会话信息存储在与我的自定义信息相同的数据库中,尽管我为会话信息指定了数据库5,为我的自定义信息指定了数据库0。一切都进入数据库0。

有谁知道我做错了什么?

谢谢

1 个答案:

答案 0 :(得分:0)

对可能重复的bean使用不同的bean id是个好主意。

@Bean    
JedisConnectionFactory jedisConnectionFactory() {...connection}

上面的函数定义了一个bean并给它一个默认的id:jedisConnectionFactory,这可能会替换你认为spring用来构造StringRedisTemplate(由spring.redis.xxx配置)的那个,这也是查找具有相同bean id的类JedisConnectionFactory的bean。结果是他们都使用{...connection}中的定义。

BTW:这是无关紧要的,但我注意到您通过注释@Bean定义了自己的bean,但是您没有以更合适的方式使用它:

@Bean(name="myJedisPool")
JedisPoolConfig jedisPoolConfig() {
}

JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {        
    // use spring managed bean.
    jedisConFactory.setPoolConfig(jedisPoolConfig);
}

@Bean(name="myRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(@Qualifier("myJedisPool") JedisPoolConfig jedisPoolConfig) {
   // use spring managed bean.
    template.setConnectionFactory( jedisConnectionFactory(jedisPoolConfig) );
}

或者你发现拥有这么多bean是没用的,所以你减少这样的bean数量:

// not a bean
JedisPoolConfig getJedisPoolConfig() {
}

// not a bean  
JedisConnectionFactory getJedisConnectionFactory() {        
    jedisConFactory.setPoolConfig(getJedisPoolConfig());
}

// only this is bean, because consumers are expecting this.
@Bean(name="myRedisTemplate")
public RedisTemplate<String, Object> redisTemplate() {
    template.setConnectionFactory( getJedisConnectionFactory() );
}