前言
RedisTemplate这是SpringBoot默认提供的Redis模板,在真实项目中肯定不会直接使用该模板,我们应该去自己定义该模板的一些属性。这篇文章主要总结SpringBoot与Redis的简单集成与可能碰到的问题。
一.集成过程
下面就总结下这个过程,主要是引入依赖、修改配置文件、初次测试。
1.引入redis的依赖
这里引入的是SpringBoot提供的启动器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.修改application.properties配置文件
#redis相关配置 spring.redis.host=192.168.150.101 spring.redis.port=6379 spring.redis.database=0
3.测试redis的使用
这样我们就完成了一个简单的SpringBoot与Redis的整合,接下来就简单的测试下是否可以正常使用。创建测试接口,RedisTemplate是SpringBoot默认注入的对象。我们可以直接获取。
@Controller public class TestRedisController { @Autowired RedisTemplate redisTemplate; @RequestMapping("/test") public void test(){ //设置键的序列化策略 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置值得序列化策略 redisTemplate.setValueSerializer(new StringRedisSerializer()); //获取值,这个过程自动反序列化 redisTemplate.opsForValue().set("key","value"); System.out.println(redisTemplate.opsForValue().get("key")); } }
启动项目,执行以上代码,结果如下图:
请忽略以上的报错,报错是没有设置返回的原因。控制台中可以看到我们已经正常拿到了我们设置的key的值value。说明集成成功,且以上代码的写法是标准的(String,String)格式存储到redis时的标准写法。
二.可能出现的问题
上面是我们在控制器中使用的RedisTemplate模板,发现可以正常使用,不过有些场景注入RedisTemplate是注入不进去的,使用时会发现值是null。
1.获取不要RedisTemplate的场景
如下代码,我们写了个破产版的redis的工具类,使用@Bean的方式将工具类注入到Spring容器中。在这个类中我们再来获取下RedisTemplate的对象,这时候有时候会获取不到。
public class TestNull { @Autowired RedisTemplate redisTemplate; public void set(String key,String value){ System.out.println("redisTemplate值:"+redisTemplate); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.opsForValue().set(key,value); } public String get(String key){ redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); return (String)redisTemplate.opsForValue().get(key); } }
若是获取不到,改为如下实现即可正常使用:
public class TestNull { @Autowired RedisTemplate redisTemplate; public static RedisTemplate redisTemplateself; @PostConstruct public void getRedisTemplate(){ redisTemplateself = this.redisTemplate; } public void set(String key,String value){ System.out.println("redisTemplate值:"+redisTemplateself); redisTemplateself.setValueSerializer(new StringRedisSerializer()); redisTemplateself.setValueSerializer(new StringRedisSerializer()); redisTemplateself.opsForValue().set(key,value); } public String get(String key){ redisTemplateself.setValueSerializer(new StringRedisSerializer()); redisTemplateself.setValueSerializer(new StringRedisSerializer()); return (String)redisTemplateself.opsForValue().get(key); } }
以上问题的解决方案主要是@PostConstruct注解,该注解可以保障在RedisTemplate使用之前将其对象注入进来。这样就可以解决注入为null的场景。
2.键值存入redis是乱码
如果我们使用第一个问题中展示的代码,去直接降值存入redis就会乱码,或者叫值存入的不是我们想要的值。比如我们这样使用:
@Controller public class TestRedisController { @Autowired TestNull testNull; @RequestMapping("/test2") public void test(){ testNull.set("testnull","testnull"); System.out.println(testNull.get("testnull")); } }
启动程序后访问接口,发现redis存入的是这样的键值:
显然这不是我们想要的值,我们想要的键值应该是一样的testnull,为什么呢?因为我们在使用时并没有设置键的序列化,虽然在破产版工具类中已经设置了键的序列化,但很显然并没有起作用,我们应该再次为键设置序列化,或者我们只在使用时再序列化在工具类不进行序列化也是可以的,将使用代码修改如下:
@Controller public class TestRedisController { @Autowired TestNull testNull; @RequestMapping("/test2") public void test(){ testNull.redisTemplateself.setKeySerializer(new StringRedisSerializer()); testNull.redisTemplateself.setValueSerializer(new StringRedisSerializer()); testNull.set("testnull","testnull"); System.out.println(testNull.get("testnull")); } }
这时我们再调用接口redis中的值就是正常的了,如下:
三.总结
这篇文章介绍了Springboot与Redis的基本整合,与简单使用。在真实的项目中这样是远远不够的,不过这里展示的两个问题确实是个典型,希望自己和路过的人可以引以为戒,防止再犯,下一篇将介绍下在笔者正在做的项目中是怎么应用RedisTemplate的。