您的位置:首页 > 数据库 > Redis

spring boot 框架下的redis缓存问题

2015-10-13 15:36 603 查看
最近负责公司的项目架构,需要使用缓存,最终使用redis,但是在 网上baidu、google了很久,始终没有找到redis缓存的比较好的解决方案,spring-io的网站框架sagan虽然也给了解决方案,但是总觉得和官方给的redis cachemanager不是很好的搭配(sagan自己设计了一个cachemanager),而网上的搭配并没有可以直接使用的东西,探索的结果最终如下:(可能随着spring boot的变化,我的方法也会失效,近作参考):

package hello.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.Method;

// 因为 key-value大都为 string类型的操作,所以spring提供了一个 StringTemplate 和  StringRedisConnection , 自带序列化 StringRedisSerializer
// redis-connection的实现有很多,spring自己家有提供,其他的也有提供
// 字符串序列化 : RedisSerializer interface (package org.springframework.data.redis.serializer)
// 常用的两种序列化 : StringRedisSerializer 和 the JdkSerializationRedisSerializer
// json的序列化 :JacksonJsonRedisSerializer or Jackson2JsonRedisSerializer 和   oxm
//
// 注意 redis 的 transactional 和  pipeline 的设置
//
// redis脚本支持
//
//  org.springframework.data.redis.support的支持类
//
//  <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate"/> ??
//
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{

// @Bean
// public KeyGenerator wiselyKeyGenerator(){
//     return new KeyGenerator() {
//         @Override
//         public Object generate(Object target, Method method, Object... params) {
//             StringBuilder sb = new StringBuilder();
//             sb.append(target.getClass().getName());
//             sb.append(method.getName());
//             for (Object obj : params) {
//                 sb.append(obj.toString());
//             }
//             return sb.toString();
//         }
//     };

// }

// @Bean
//    public RedisTemplate<String, String> redisTemplate(
//            RedisConnectionFactory factory) {

@Bean
public StringRedisTemplate redisTemplate(
RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
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);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}

// StringRedisTemplate
@Bean
public CacheManager cacheManager(StringRedisTemplate template) {
return new RedisCacheManager(template);
}

}


注意,我的redisTemplate方法直接返回了StringRedisTemplate,如果返回redisTemplate则会造成一个接口多个实现Ioc异常,cachemanager中的方法也使用了StringRedisTemplate,保持一致(改成redisTemplate也会造成ioc的实现异常)。

坑, 表示官方竟然不给一个详细的文档!在官方源代码中,也没有很好的说明,甚至redis作为cache,在cacheType中有,但是在cacheProperties中就消失了(实现上的问题?)

[align=right]徐建海[/align]

[align=right]2015.10.13[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息