最近稍有闲暇,于是研究了一下springboot与redis整合。之前是做过springboot1.5.4与redis的整合,最新版本已经到了2.1.0,索性针对当前的最新版本做了一次整合。
最基础的整合是比较容易的,按官方文档编写代码就ok了。我简单罗列一下,关键配置和主要的代码。
###redis 配置
```
#索引库
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=xxxxx
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
```
### 定义configuration
```
@Configuration
@EnableCaching
public class RedisConfig{
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory factory){
RedisCacheConfiguration defaultCacheConfig = getRedisCacheConfiguration();
return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
.cacheDefaults(defaultCacheConfig)
.initialCacheNames(new HashSet<>(Arrays.asList("third_users")))
.build();
}
public RedisCacheConfiguration getRedisCacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(24));
}
}
```
### 使用
```
package cn.cube.gopher.dao.impl;
import cn.cube.base.core.cache.KeyParam;
import cn.cube.base.core.common.Query;
import cn.cube.base.core.dao.BaseCacheDao;
import cn.cube.base.core.dao.IIdDao;
import cn.cube.base.core.db.DB;
import cn.cube.base.core.db.Pagination;
import cn.cube.base.core.util.CollectionUtils;
import cn.cube.gopher.entity.ThirdUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
/**
* Description:UserThirdDao
* Date:2018/3/11
*/
@Repository
public class ThirdUserDao extends BaseCacheDao<String, ThirdUser> implements IIdDao<String, ThirdUser> {
@Autowired
private DB db;
@Cacheable(value = "third-user", key="#openId")
public ThirdUser query(@KeyParam String openId) {
return db.from(ThirdUser.class).where("open_id", openId).first(ThirdUser.class);
}
@CacheEvict
public int update(@KeyParam(key = "openId") ThirdUser userThird) {
return db.update(userThird, "sex", "nick", "head", "country", "province", "city");
}
}
```
### JSON序列化
由于jdk序列化后的数据为二进制数据,没法一眼查看数据详情。springdata是支持自定义序列化的,并且提供了JSON相关的序列化类。改写getRedisCacheConfiguration方法如下。
```
public RedisCacheConfiguration getRedisCacheConfiguration() {
Jackson2JsonRedisSerializer 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);
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(24)).serializeValuesWith(pair);
}
```
### 异常
springdata默认使用的jdk序列化工具,所以要求缓存对象必须实现Serializable接口
```
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [cn.cube.gopher.entity.ThirdUser]
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
at org.springframework.data.redis.serializer.DefaultRedisElementWriter.write(DefaultRedisElementWriter.java:43)
at org.springframework.data.redis.serializer.RedisSerializationContext$SerializationPair.write(RedisSerializationContext.java:241)
at org.springframework.data.redis.cache.RedisCache.serializeCacheValue(RedisCache.java:238)
at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:144)
```
@Cacheable 未设置value时,系统无法匹配对应的缓存处理对象
```
java.lang.IllegalStateException: No cache could be resolved for 'Builder[public cn.cube.gopher.entity.ThirdUser cn.cube.gopher.dao.impl.ThirdUserDao.query(java.lang.String)] caches=[] | key='#openId' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@41143873'. At least one cache should be provided per cache operation.
at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:255)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.java:707)
at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:265)
```
转载保留出处[http://threeperson.com/articles/2143](http://threeperson.com/articles/2143)