最近项目中用到了redis实现session共享和缓存存储,那么实现这两点并不难,网上也有大量的例子,那么问题在于两者如何能够分别保存在不同的redis中,以方便管理呢。
首先先说如何实现session共享和缓存存储
1.引入架包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
2.添加配置文件
添加数据源和连接工厂,这里我用了集群
<!-- 连接池相关配置信息 -->
<bean id="redisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="minIdle" value="${redis.pool.minIdle}" />
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
<property name="testOnReturn" value="${redis.pool.testOnReturn}" />
</bean>
<!-- Sentinel配置信息 -->
<bean id="redisSentinelConf"
class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="myMaster" />
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinel.01.host}" />
<constructor-arg name="port" value="${redis.sentinel.01.port}" />
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinel.02.host}" />
<constructor-arg name="port" value="${redis.sentinel.02.port}" />
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinel.03.host}" />
<constructor-arg name="port" value="${redis.sentinel.03.port}" />
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinel.04.host}" />
<constructor-arg name="port" value="${redis.sentinel.04.port}" />
</bean>
</set>
</property>
</bean>
<!-- redis连接工厂配置 -->
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="sentinelConfig" ref="redisSentinelConf" />
<constructor-arg name="poolConfig" ref="redisPoolConfig" />
<property name="usePool" value="true" />
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.db}" />
</bean>
<!-- redis模板配置,默认key和value均为stringSerializer序列化方式 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<!-- 事务配置,设置为true支持绑定连接执行事务内的命令 -->
<property name="enableTransactionSupport" value="false" />
</bean>
3.将session交给redis管理
<bean
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>
配置以上几步就可以实现将session存放在redis中,实现session共享了
4.缓存存储
需要自定义一个工具类
@qualifier()中为我们在上面配置redis模板bean的id
@Qualifier("redisTemplate")
public RedisTemplate redisTemplate;
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key
* 缓存的键值
* @param value
* 缓存的值
* @return 缓存的对象
*/
public <T> ValueOperations<String, T> setCacheObject(String key, T value) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, value);
return operation;
}
/**
* 获得缓存的基本对象。
*
* @param key
* 缓存键值
* @param operation
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(String key/* ,ValueOperations<String,T> operation */) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
具体可根据自己需求写。
以上就是全部配置,但是经过测试发现session和我们写入的数据会保存在一起,这样并不方便我们进行管理,那么解决的方法就是再配置一个数据源,让session和缓存保存在不同的数据源中。
5.配置多数据源
配置第二个连接工厂,用于存储session,我这里只有一个redis服务器,所以只好换个database
<bean id="sessionredisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="sentinelConfig" ref="redisSentinelConf" />
<constructor-arg name="poolConfig" ref="redisPoolConfig" />
<property name="usePool" value="true" />
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="1" />
</bean>
使用@EnableRedisHttpSession
@Configuration
@EnableRedisHttpSession
public class SessionConfig {
private static final Logger logger=LoggerFactory.getLogger(SessionConfig.class);
@Bean
public JedisConnectionFactory connectionFactory(@Qualifier("sessionredisConnectionFactory") JedisConnectionFactory factory)
{
JedisConnectionFactory connection = new JedisConnectionFactory();
connection=factory;
if(connection!=null){
logger.info("session_jedisConnectionFactory加载成功.........");
}
return connection;
}
}
在这个方法中我们用@Qualifier指定了redis连接工厂,这样session就是找到指定的数据源实现存储,
当然第三步中的配置就要删掉了
再将这个类引入配置文件中,当然如果用了包扫描那就不用引入了。
还有另外一种方法,不使用@EnableRedisHttpSession标签
我们在第三步中配置的
<bean
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>
无法使用多数据源是因为这个类中没有为其指定连接工厂和模板
那么我们只需要重写这个类中的部分方法,同样用@Qualifier指定连接工厂和模板,然后将其引入到配置文件中即可