Springboot整合reidis详解
来源:互联网 发布:手机壳品牌知乎 编辑:程序博客网 时间:2024/06/08 11:58
springBoot集成redis的key,value序列化的相关问题
使用redis操作key-value数据
Spring Data Redis 包含了多个模版实现,用来完成Redis数据库的数据存储功能
但是为了创建spring data redis的模版,我们首先要有一个redis的链接工厂.
1.连接到redis
redis链接工厂会生成到redis数据库服务器的链接.spring data redis为四种redis客户端提供了链接工厂.
- JedisConnectionFactory
- JredisConnectionFaction
- LettuceConnectionFaction
- SrpConnectionFaction
可自行选择链接工厂.
在做出决策后,我们就可以将连接工厂配置为 spring 中的bean.
@Bean public RedisConnectionFactory redisCF(){ return new JedisConnectionFactory(); }
通过默认的构造器创建的连接工厂回想localhost上的6379端口创建连接,并且没有密码,如果你的redis运行在其他主机或者端口上,可使用链接工厂设置这些属性.
@Bean public RedisConnectionFactory redisCF(){ JedisConnectionFactory cf = new JedisConnectionFactory(); cf.setHostName("192.168.80.155"); cf.setPort(6379); return cf; }
现在我们有了链接工厂,接下来皆可以使用spring data redis模版了
2.使用 RedisTemplate
顾名思义,Redis连接工厂会生成到 redis key-value 的存储连接(以RedisConnection的形式).
借助connection我们就可以读取数据.
与其它的 spring data项目类似,spring data redis以模版的形式提供了较高等级的数据访问方案,实际上,有两个模版:
- RedisTemplate
- StringRedisTemplate
@Configurationpublic class CacheConfig { @Bean public RedisConnectionFactory redisCF(){ JedisConnectionFactory cf = new JedisConnectionFactory(); cf.setHostName("192.168.80.155"); cf.setPort(6379); return cf; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf){ RedisTemplate<String,String> template = new RedisTemplate<String,String>(); template.setConnectionFactory(cf); return template; }}
有了RedisTemplate之后,我们就可以操作key-value条目了,关于RedisTemplate的API,可以去网上详细查看
测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring-context.xml"}) public class CacheTest { @Autowired private RedisTemplate redisTemplate; @Test public void test1(){ ValueOperations opsForValue = redisTemplate.opsForValue(); opsForValue.set("test1", "hello redis"); }}
3.使用key 和value的序列化器
当某个条目保存到Redis key-value存储的时候,key和value都会使用redis的序列化器进行序列化.Spring data Redis提供了多个这样的序列化器.
* StringRedisSerializer 序列化String类型的key 和value
* GenericToStringSerializer 使用Spring转换器进行序列化.
* Jackson2JsonRedisSerializer 使用jackson2,将对象序列化为json
* JdkSerializationRedisSerializer 使用java序列化
* OxmSerializer 用于XML序列化
RedisTemplate 默认会使用 JdkSerializationRedisSerializer,这意味着key和value都会通过java进行序列化.
StringRedisTemplate 默认会使用 StringRedisSerializer ,这在我们意料之中.
设置key和value的序列化器
@Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf){ RedisTemplate<String,String> template = new RedisTemplate<String,String>(); //key会被转换为String类型,非String类型会报错 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //设置序列化为 json的对象类型,必须实现 serializable接口 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); template.setConnectionFactory(cf); template.setKeySerializer(stringRedisSerializer); template.setValueSerializer(jackson2JsonRedisSerializer); return template; }
Spring 声明式缓存
Spring 对缓存的支持有两者方式:
- 注解驱动的支持
- XML声明的缓存
使用Spring的缓存抽象时,最为通用的方法就是在方法上添加 @Cacheable 注解 和 @CacheEvict 注解.
在往bean方法上添加缓存之前,必须先启用Spring对注解驱动缓存的支持.
如果我们使用java配置的话,可以在一个配置类上添加 @EnableCaching ,这样就能启用注解驱动的缓存
@Configuration@EnableCachingpublic class AnnoCacheConfig { //声明缓存管理器 @Bean public CacheManager cacheManager(){ CacheManager cacheManager = new ConcurrentMapCacheManager(); return cacheManager; }}
在上例中我们还声明了一个缓存管理器的bean.缓存管理器是Spring抽象的核心,它能够与多个流行的缓存实现进行集成
在本例中声明了 ConcurrentMapCacheManager,这个简单的缓存管理器,是基于内存的,所以它的声明周期是与应用相关联的,
幸好,有多个很棒的缓存管理器方案可供使用.
在为 Spring的缓存抽象选择管理器时,我们有很多可选的方案,具体悬着哪一种,取决于想要使用的底层缓存供应商.
我们必须选择一个缓存管理器,应用在Spring上下文中,以bean的形式对其进行配置,对于Redis,Spring data 为我们提供了 RedsiCacheManager,接下来让我们看一下如何配置吧.
配置注解式 Redis缓存
Spring Data Redis 提供了一个RedisCachemanager ,这是manager的一个实现.RedsiCacheManager 会与一个Redis服务器协作,并通过RedisTemplate将缓存条目存储到Redia中.
为了使用 RedisCachemanager,我们需要Template的bean以及RedisConnectionFaction的实现类(如JedisConnectionFactory)的一个bean,
@Configuration@EnableCachingpublic class CacheConfig { //缓存管理器 @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); // Number of seconds before expiration. Defaults to unlimited (0) cacheManager.setDefaultExpiration(3000); // Sets the default expire time (in seconds) return cacheManager; } //连接工厂 @Bean public RedisConnectionFactory redisCF(){ JedisConnectionFactory cf = new JedisConnectionFactory(); cf.setHostName("192.168.80.155"); cf.setPort(6379); return cf; } //RedisTemplate @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf){ RedisTemplate<String,String> template = new RedisTemplate<String,String>(); //key会被转换为String类型,非String类型会报错 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //设置序列化为 json的对象类型,必须实现 serializable接口 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); template.setConnectionFactory(cf); template.setKeySerializer(stringRedisSerializer); template.setValueSerializer(jackson2JsonRedisSerializer); return template; }// @Bean// public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory cf){// return new StringRedisTemplate();// }}
可以看到,我们构建了一个RedisCacheManager,这是通过传递一个 RedisTemplate 的示例作为其构造器的参数实现的.
注意:上面的配置,在序列化非String的key时,会报错,我们可以自定义key的生成策略,首先我们炫耀继承 CachingConfigurerSupport,完整配置如下:
package cn.yearcon.shop.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.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;/** * redis * * @author itguang * @create 2017-10-31 8:26 **/@Configuration@EnableCachingpublic class CacheConfig extends CachingConfigurerSupport { /** * 自定义key. * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { System.out.println("RedisCacheConfig.keyGenerator()"); return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { // This will generate a unique key of the class name, the method name //and all method parameters appended. StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } System.out.println("keyGenerator=" + sb.toString()); return sb.toString(); } }; } @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate); //设置缓存过期时间 60秒*30 redisCacheManager.setDefaultExpiration(60*30); //设置value的过期时间 Map<String,Long> map=new HashMap(); map.put("category",10*60L);//10分钟 map.put("product",10*60L);//10分钟 redisCacheManager.setExpires(map); return redisCacheManager; } @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); //定义key序列化方式 RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要 //定义value的序列化方式 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); //给 redisTemplate 设置 key 和value的生成策略 redisTemplate.setKeySerializer(redisSerializer); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }}
为方法添加注解以支持缓存
Spring的缓存抽象在很大程度上是围绕切面构建的,在Spring启用缓存时会创建一个切面,它会触发一个或更多的缓存注解,所有的注解都能运用在类或方法上,当其运用在单个方法上时,注解所描述的缓存只会运用到这个方法上,如果注解放在类级别上的话,那么缓存就会应用到这个类的所有商法上
Spring提供了四个注解来声明缓存规则
* @Cacheable 表明Spring在调用方法前,应该首先在缓存中查找方法的返回值,如果这个值能够找到,就返回缓存的值,否则的话买这个方法就会被调用,返回值放到缓存之中
* @CacheEvict 表明Spring应该在缓存中清楚一个或者多个条目
* @CachePut 表明Spring应该将方法的返回值放到缓存中,方法的调用并不会检查缓存,方法始终都会被调用
* @Caching 这是一个分组的注解,能够同时应用多个其他的缓存注解
具体注解的API参考其它资料
- Springboot整合reidis详解
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
- SpringBoot开发详解(十一) -- Redis在SpringBoot中的整合
- springboot与mybatis整合实例详解(完美融合)
- SpringBoot开发详解(七)-- Mybatis整合Spring Boot
- springboot与mybatis整合 实例详解(完美融合)
- SpringBoot学习:SpringBoot整合mybatis
- SpringBoot整合Mybatis(分层整合)
- springboot整合freemarker
- SpringBoot和Mybatis整合
- springboot整合jsp
- el表达式
- 提交spark任务Requesting 1 new executor because tasks are backlogged (new desired total will be 1)
- JavaScript——变量提升
- Markdown 表格编辑
- Hook技术activity启动过程中拦截(无需在androidmanifest文件注册即可使用)
- Springboot整合reidis详解
- 项目总结(2)
- 深度学习的应用以及初识Tensorflow
- java学习-开篇
- erlang 学习ets表-1
- Java的三种代理模式
- Docker for Mac阿里云Docker加速器设置
- 闭包
- Linux 服务器配置