转:https://blog.csdn.net/jaryle/article/details/81480557

1.引入reids包

spring-boot-starter-redis(springboot版本1.4版本前),spring-boot-starter-data-redis(1.4版本后)

选择合适的API:

这个主要是根据redis存储的数据类型需求决定,key一般都是String,但是value可能不一样,一般有两种,String和 Object; 
如果k-v都是String类型,我们可以直接用 StringRedisTemplate,这个是官方建议的,也是最方便的,直接导入即用,无需多余配置! 
如果k-v是Object类型,则需要自定义 RedisTemplate,在这里我们都研究下!

2.配置文件application.yml中redis的配置信息

redis:
  host: 127.0.0.1
  port: 6379
  #连接超时时间(毫秒)
  timeout: 2000
  pool:
    #最大连接数(负数表示没有限制)
    max-active: 100
    #最大空闲连接
    max-idle: 10
    #最大阻塞等待时间(负数表示没有限制)
    max-wait: 100000   
  database: 0

3.Redis配置类(注意这里使用spring boot 1.x版本如果2.x版本缓存管理器写法不一样,不再使用RedisTemplate构造,而是使用了RedisConnectionFactory)

@Configuration
@EnableCaching //配置cache Manager
//继承CachingConfigurerSupport类是为了自定义redis key的生成策略(复写keyGenerator方法)
public class RedisConfig extends CachingConfigurerSupport{//从配置文件中读取配置信息@Value("${redis.timeout}")private Long redisTimeout;/*生成key的策略 根据类名+方法名+所有参数的值生成唯一的一个key **/@Bean@Overridepublic KeyGenerator keyGenerator() {return new KeyGenerator() {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();}};}/*** 管理缓存* @param redisTemplate* @return*/@Beanpublic CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);//设置redis缓存过期时间cacheManager.setDefaultExpiration(redisTimeout);return cacheManager; } /*** RedisTemplate配置* jdk序列方式,用来保存对象(key=对象)* @param factory* @return*//*@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//自定义的redis序列化工具类(对object序列化)RedisObjectSerializer redisObjectSerializer = new RedisObjectSerializer();RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(factory);template.setKeySerializer(stringRedisSerializer);template.setValueSerializer(redisObjectSerializer);return template; } *//*** RedisTemplate配置* string的序列化方式,存储string格式(key=value)* @param factory* @return*//*@Beanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); stringRedisTemplate.setConnectionFactory(factory);setSerializer(stringRedisTemplate);stringRedisTemplate.afterPropertiesSet();return stringRedisTemplate; }*//*private void setSerializer(StringRedisTemplate template){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);}*//*** redis模板,存储关键字是字符串,值是Jdk序列化,这个写法和我com.jary.util中的RedisObjectSerializer写法更简单,测试后选择使用那个* @Description:* @param factory* @return*/@Beanpublic RedisTemplate<?,?> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<?,?> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);//key序列化方式;但是如果方法上有Long等非String类型的话,会报类型转换错误;RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;redisTemplate.setKeySerializer(redisSerializer);redisTemplate.setHashKeySerializer(redisSerializer);//JdkSerializationRedisSerializer序列化方式;JdkSerializationRedisSerializer jdkRedisSerializer=new JdkSerializationRedisSerializer();redisTemplate.setValueSerializer(jdkRedisSerializer);redisTemplate.setHashValueSerializer(jdkRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate; }

或者

redis的配置类
有两种配置类
@Configuration //当前类为配置类
public class RedisConfig {@Bean //redisTemplate注入到Spring容器public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,String> redisTemplate=new RedisTemplate<>();RedisSerializer<String> redisSerializer = new StringRedisSerializer();redisTemplate.setConnectionFactory(factory);//key序列化redisTemplate.setKeySerializer(redisSerializer);//value序列化redisTemplate.setValueSerializer(redisSerializer);//value hashmap序列化redisTemplate.setHashKeySerializer(redisSerializer);//key hashmap序列化redisTemplate.setHashValueSerializer(redisSerializer);return redisTemplate;}
}@Slf4j
@Configuration
public class RedisConfig {@Bean@SuppressWarnings("all")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(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);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}

里面写的有点乱,主要是使用几种序列化的方式不同,不用的都注释掉了,其中有一个<String,Object>的RedisTemplate,里面使用了自定义的序列化方式工具类redisObjectSerializer:

/*** @Author: jaryle* @CreateDate: 2018/6/3 14:24* @Version: 1.0*/
public class RedisObjectSerializer implements RedisSerializer<Object> {static final byte[] EMPTY_ARRAY = new byte[0];@Overridepublic Object deserialize(byte[] bytes) {if (isEmpty(bytes)) {return null;}ObjectInputStream oii = null;ByteArrayInputStream bis = null;bis = new ByteArrayInputStream(bytes);try {oii = new ObjectInputStream(bis);Object obj = oii.readObject();return obj;} catch (Exception e) {e.printStackTrace();}return null;}@Overridepublic byte[] serialize(Object object) {if (object == null) {return EMPTY_ARRAY;}ObjectOutputStream obi = null;ByteArrayOutputStream bai = null;try {bai = new ByteArrayOutputStream();obi = new ObjectOutputStream(bai);obi.writeObject(object);byte[] byt = bai.toByteArray();return byt;} catch (IOException e) {e.printStackTrace();}return null;}private boolean isEmpty(byte[] data) {return (data == null || data.length == 0);}}

刚开始使用此方法进行测试的,测试成功,后来觉得太麻烦,还要自己写个序列化工具类,就使用现在没有注释的RedisTemplate<?,?>更简单一些,功能也可以实现。

4.编写一个  redis封装工具类:(内部导入的是StringRedisTemplate,RedisTemplate也可以)

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;/*** @Author: jaryle* @Date: 2018/08/08 17:30*/
@Service
@Slf4j
public class IRedisService {
//这里我们注入了我自定义的Redistemplate,而且支持<String,Object>存储,上面写出自定义序列化@Autowiredprotected RedisTemplate redisTemplate;private final static Logger log = LoggerFactory.getLogger(RedisUtils.class);/*** 写入redis缓存(不设置expire存活时间)* @param key* @param value* @return*/public boolean set(final String key, String value){boolean result = false;try {ValueOperations operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch (Exception e) {log.error("写入redis缓存失败!错误信息为:" + e.getMessage());}return result;}/*** 写入redis缓存(设置expire存活时间)* @param key* @param value* @param expire* @return*/public boolean set(final String key, String value, Long expire){boolean result = false;try {ValueOperations operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expire, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.error("写入redis缓存(设置expire存活时间)失败!错误信息为:" + e.getMessage());}return result;}/*** 读取redis缓存* @param key* @return*/public Object get(final String key){Object result = null;try {ValueOperations operations = redisTemplate.opsForValue();result = operations.get(key);} catch (Exception e) {log.error("读取redis缓存失败!错误信息为:" + e.getMessage());}return result;}/*** 判断redis缓存中是否有对应的key* @param key* @return*/public boolean exists(final String key){boolean result = false;try {result = redisTemplate.hasKey(key);} catch (Exception e) {log.error("判断redis缓存中是否有对应的key失败!错误信息为:" + e.getMessage());}return result;}/*** redis根据key删除对应的value* @param key* @return*/public boolean remove(final String key){boolean result = false;try {if(exists(key)){redisTemplate.delete(key);}result = true;} catch (Exception e) {log.error("redis根据key删除对应的value失败!错误信息为:" + e.getMessage());}return result;}/*** redis根据keys批量删除对应的value* @param keys* @return*/public void remove(final String... keys){for(String key : keys){remove(key);}}
}

上面代码,都是key=value形式的操作。如果key=value(object),stringRedisTemplate就不能使用了,我们要自定义一个redisTemplate来处理。

springboot也提供了RedisTemplate

定义了对5种数据结构操作:

redisTemplate.opsForValue();//操作字符串

redisTemplate.opsForHash();//操作hash

redisTemplate.opsForList();//操作list

redisTemplate.opsForSet();//操作set

redisTemplate.opsForZSet();//操作有序set

5.使用的是mybatis,持久层我就不上代码了,直接上service吧

@ComponentScan({"com.jary.mapper"})
@Service
public class UserServiceImpl implements UserService {@ResourceUserMapper userMapper;@AutowiredRedisUtils redisUtis;@Overridepublic List<User> getUsers() {return  userMapper.getUsers();}@Overridepublic User getUserById(User user) {// TODO Auto-generated method stubreturn null;}@Overridepublic User selectUser(String user_name) {User usr = userMapper.selectUser(user_name);//把usr信息写入缓存中redisUtis.set("usr_id", usr);return usr;} 

6.controller层也不用写了吧,太简单浪费时间,直接上测试结果

7.最后说说StringRedisTemplate 和 RedisTemplate 对比分析

总结了一下区别和联系主要有四点:

第一点,StringRedisTemplate继承了RedisTemplate。

第二点,RedisTemplate是一个泛型类,而StringRedisTemplate则不是。

第三点,StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作。

第四点,是他们各自序列化的方式不同,但最终都是得到了一个字节数组,殊途同归,StringRedisTemplate使用的是StringRedisSerializer类;RedisTemplate使用的是JdkSerializationRedisSerializer类。反序列化,则是一个得到String,一个得到Object

8。源码分析:

先看 StringRedisTemplate:

StringRedisTemplate 是继承 RedisTemplate的,一般来说子类继承父类,应该能实现更多的功能,但是此处我们发现 StringRedisTemplate 继承的是 RedisTemplate的泛型类,指定了String-String的泛型!故功能只专注于String类型!

其次我们可以看到 StringRedisTemplate 的构造方法中指定了序列化类为 StringRedisSerializer,我们进去看看

这下就一目了然了!

再看 RedisTemplate:

可以看到默认序列化方式为 JdkSerializationRedisSerializer:

而JdkSerializationRedisSerializer又调用了SerializingConverter类的convert方法。在这个方法里其转换主要有三步:

1、ByteArrayOutputStream(1024),创建一个字节数组输出流缓冲区。

2、DefaultSerializer.serialize(source, byteStream):把要序列化的数据存储到缓冲区。还想看他是怎么放到缓冲区的,但是,能力有限,水平一般,serialize的细节,实在无能为力,看了半天,还是氐惆。

3、toByteArray:就是把上一步放到缓冲区的数据拷贝到新建的字节数组里。

至此Object的序列化就结束了,返回了一个字节数组。

spring boot + redis 配置相关推荐

  1. Spring Boot Redis 入门

    本文,我们基于 Spring Boot 2.X 版本. 1. 概述 在快速入门 Spring Boot 整合 Redis 之前,我们先来做个简单的了解.在 Spring 的生态中,我们使用 Sprin ...

  2. java+cache使用方法_java相关:Spring boot redis cache的key的使用方法

    java相关:Spring boot redis cache的key的使用方法 发布于 2020-8-16| 复制链接 摘记: 在数据库查询中我们往往会使用增加缓存来提高程序的性能,@Cacheabl ...

  3. Spring Boot Redis Cluster 实战干货

    转载自  Spring Boot Redis Cluster 实战干货 添加配置信息 spring.redis:database: 0 # Redis数据库索引(默认为0)#host: 192.168 ...

  4. Spring Boot Redis缓存

    Spring Boot Redis缓存 目录[ 隐藏 ] 1 Spring Boot Redis缓存 1.1 Spring Boot Redis项目设置 1.2 Spring Boot Redis缓存 ...

  5. 太好了 | 这篇写的太好了!Spring Boot + Redis 实现接口幂等性

    Hi ! 我是小小,今天是本周的第四篇,第四篇主要内容是 Spring Boot + Redis 实现接口幂等性 介绍 幂等性的概念是,任意多次执行所产生的影响都与一次执行产生的影响相同,按照这个含义 ...

  6. springboot自动配置原理_今日份学习之Spring Boot自动配置实现原理

    通过前面章节的学习,我们掌握了使用Spring Boot框架进行实际应用开发的方法.在使用Spring Boot 的过程中,我们时常会为一些看似简单,但实际上蕴藏了强大功能的实现而惊呼,下面就让我们来 ...

  7. Spring Boot Redis关闭

    Spring Boot Redis 在开发或者本地没有redis数据库时,控制台会一直报连接超时的日志,可以通过配置取消: spring: data:redis:repositories:enable ...

  8. Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件

    本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 图 2 第二章目录结构图 第 2 章 Spr ...

  9. Spring Boot 属性配置和使用

    spring Boot 允许通过外部配置让你在不同的环境使用同一应用程序的代码,简单说就是可以通过配置文件来注入属性或者修改默认的配置. Spring Boot 系列 Spring Boot 入门 S ...

最新文章

  1. spring中@Value的注解解析
  2. 做事情不要着急,着急只能把事情做的更加糟糕。。。
  3. python保存csv_python怎样保存csv文件
  4. MyBatis的功能架构是怎样的
  5. Google Xpath Helper
  6. LSGO软件技术团队2015~2016学年第八周(1019~1025)总结
  7. 微软发布Enterprise Library 4.1和Unity 1.2
  8. atitit.atiOrmStoreService 框架的原理与设计 part1  概述与新特性
  9. PHP服务Fcgi进程及PHP解析优化
  10. 基于visual Studio2013解决面试题之0202上下排
  11. 聊一聊数学中的基本定理(二)——算术基本定理的价值
  12. 计算机第一个应用领域是,第一代计算机主要应用领域是什么
  13. JS获取手机型号和系统版本
  14. mmdetection使用
  15. 如何更好的保护个人信息
  16. 1.5万倍超高回报率、融合盲盒玩法背后,NFT仍是巨鲸乐园
  17. 高动态卫星DSSS信号Turbo迭代捕获算法
  18. 【HTTP】10分钟带你快速了解HTTP中常见的状态码(内附大量实例)
  19. 鸭子的应聘 我是学c 的
  20. 未来软件产业教育之我见[转]

热门文章

  1. 北京决心一试:如何打造中国的HHMI和贝尔实验室?道翰天琼认知智能api机器人接口1。
  2. android全局监听onkeydown,Android中的几个onTouch()事件、onKeyDown监听返回键无效
  3. 推荐一个在线音乐播放网站
  4. 2018年12月六级考试真题笔记
  5. 简单聊一聊 Python 有哪几方面的应用
  6. 要求用户输入一个电子邮件。验证电子邮件格式是否正确。 电子邮件格式:XX@XX.com 实现方式:该字符串中必须包含@字符串和.字符串。 @不能出现在第一个位置,并且@位置大于.;
  7. Java-练习题-002-继承
  8. 计算机乘法怎么操作函数,计算机word乘积函数
  9. 学习Java-JavaSE的必备工具(内附各种工具的下载链接)
  10. 从工程师到管理者,角色到底发生了哪些变化?