博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis 学习笔记(5)-Spring与Jedis的集成
阅读量:4037 次
发布时间:2019-05-24

本文共 8243 字,大约阅读时间需要 27 分钟。

首先不得不服Spring这个宇宙无敌的开源框架,几乎整合了所有流行的其它框架,从这上面看,当下流行的redis、solr、hadoop、mongoDB、couchBase... 全都收入囊中。对于redis整合而言,主要用到的是spring-data-redis

 原文地址:http://www.cnblogs.com/yjmyzz/p/integrate-redis-with-spring.html

使用步骤:

一、pom添加依赖项

org.springframework.data
spring-data-redis
1.4.1.RELEASE

其它Spring必备组件,比如Core,Beans之类,大家自行添加吧

观察一下:

jedis、jredis等常用java的redis client已经支持了,不知道以后会不会集成Redisson,spring-data-redis提供了一个非常有用的类:StringRedisTemplate

对于大多数缓存应用场景而言,字符串是最常用的缓存项,用StringRedisTemplate可以轻松应付。

 

二、spring配置

1     
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 26
28
29
30 31
32
33

这里我们使用Sentinel模式来配置redis连接,从知道,sentinel是一种高可用架构,个人推荐在生产环境中使用sentinel模式。

注:26-28行,经试验,如果修改了默认端口,这里必须明细指定hostName及port,否则运行后,无法正确读写缓存,参考下面的配置:

其中hostName为当前master的IP,port为redis-server的运行端口(非sentinel端口),此外还要设置usePool为false,由于sentinel可能会自行切换master节点,如果不清楚当前的master节点是哪台机器,可以用前面提到的命令./redis-cli -p <sentinal端口号> sentinel masters查看,或者用java代码输出,参考下面的代码:

1         ApplicationContext ctx = new FileSystemXmlApplicationContext("/opt/app/spring-redis.xml");2         StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);3         for (RedisServer m : template.getConnectionFactory().getSentinelConnection().masters()) {4             logger.debug(m);5         }

 

三、单元测试

1     @Test 2     public void testSpringRedis() { 3         ConfigurableApplicationContext ctx = null; 4         try { 5             ctx = new ClassPathXmlApplicationContext("spring.xml"); 6  7             StringRedisTemplate stringRedisTemplate = ctx.getBean("stringRedisTemplate", StringRedisTemplate.class); 8  9             // String读写10             stringRedisTemplate.delete("myStr");11             stringRedisTemplate.opsForValue().set("myStr", "http://yjmyzz.cnblogs.com/");12             System.out.println(stringRedisTemplate.opsForValue().get("myStr"));13             System.out.println("---------------");14 15             // List读写16             stringRedisTemplate.delete("myList");17             stringRedisTemplate.opsForList().rightPush("myList", "A");18             stringRedisTemplate.opsForList().rightPush("myList", "B");19             stringRedisTemplate.opsForList().leftPush("myList", "0");20             List
listCache = stringRedisTemplate.opsForList().range(21 "myList", 0, -1);22 for (String s : listCache) {23 System.out.println(s);24 }25 System.out.println("---------------");26 27 // Set读写28 stringRedisTemplate.delete("mySet");29 stringRedisTemplate.opsForSet().add("mySet", "A");30 stringRedisTemplate.opsForSet().add("mySet", "B");31 stringRedisTemplate.opsForSet().add("mySet", "C");32 Set
setCache = stringRedisTemplate.opsForSet().members(33 "mySet");34 for (String s : setCache) {35 System.out.println(s);36 }37 System.out.println("---------------");38 39 // Hash读写40 stringRedisTemplate.delete("myHash");41 stringRedisTemplate.opsForHash().put("myHash", "PEK", "北京");42 stringRedisTemplate.opsForHash().put("myHash", "SHA", "上海虹桥");43 stringRedisTemplate.opsForHash().put("myHash", "PVG", "浦东");44 Map
hashCache = stringRedisTemplate.opsForHash()45 .entries("myHash");46 for (Map.Entry
entry : hashCache.entrySet()) {47 System.out.println(entry.getKey() + " - " + entry.getValue());48 }49 50 System.out.println("---------------");51 52 } finally {53 if (ctx != null && ctx.isActive()) {54 ctx.close();55 }56 }57 58 }

运行一下,行云流水般的输出:

...

信息: Created JedisPool to master at 10.6.144.***:7030
http://yjmyzz.cnblogs.com/
---------------
0
A
B
---------------
C
B
A
---------------
SHA - 上海虹桥
PVG - 浦东
PEK - 北京
---------------

...

注意红色标出部分,从eclipse控制台的输出,还能看出当前的master是哪台服务器

 

三、POJO对象的缓存

Spring提供的StringRedisTemplate只能对String操作,大多数情况下已经够用,但如果真需要向redis中存放POJO对象也不难,我们可以参考StringRedisTemplate的源码,扩展出ObjectRedisTemplate

1 package org.springframework.data.redis.core; 2  3 import org.springframework.data.redis.connection.DefaultStringRedisConnection; 4 import org.springframework.data.redis.connection.RedisConnection; 5 import org.springframework.data.redis.connection.RedisConnectionFactory; 6 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 7 import org.springframework.data.redis.serializer.RedisSerializer; 8  9 public class ObjectRedisTemplate
extends RedisTemplate
{10 11 public ObjectRedisTemplate(RedisConnectionFactory connectionFactory,12 Class
clazz) {13 14 RedisSerializer
objectSerializer = new Jackson2JsonRedisSerializer
(15 clazz);16 17 RedisSerializer
objectKeySerializer = new Jackson2JsonRedisSerializer
(18 String.class);19 20 setKeySerializer(objectKeySerializer);21 setValueSerializer(objectSerializer);22 setHashKeySerializer(objectSerializer);23 setHashValueSerializer(objectSerializer);24 25 setConnectionFactory(connectionFactory);26 afterPropertiesSet();27 }28 29 protected RedisConnection preProcessConnection(RedisConnection connection,30 boolean existingConnection) {31 return new DefaultStringRedisConnection(connection);32 }33 }

然后就可以这样用了:

1     @Test 2     public void testSpringRedis() { 3         ConfigurableApplicationContext ctx = null; 4         try { 5             ctx = new ClassPathXmlApplicationContext("spring.xml"); 6  7             JedisConnectionFactory connFactory = ctx.getBean( 8                     "jedisConnFactory", JedisConnectionFactory.class); 9 10             ObjectRedisTemplate
template = new ObjectRedisTemplate
(11 connFactory, SampleBean.class);12 13 template.delete("myBean");14 SampleBean bean = new SampleBean("菩提树下的杨过");15 template.opsForValue().set("myBean", bean);16 17 System.out.println(template.opsForValue().get("myBean"));18 19 } finally {20 if (ctx != null && ctx.isActive()) {21 ctx.close();22 }23 }24 }

其中SampleBean的定义如下:

1 package com.cnblogs.yjmyzz; 2  3 import java.io.Serializable; 4  5 public class SampleBean implements Serializable { 6  7     private static final long serialVersionUID = -303232410998377570L; 8  9     private String name;10 11     public SampleBean() {12     }13 14     public SampleBean(String name) {15         this.name = name;16     }17 18     public String getName() {19         return name;20     }21 22     public void setName(String name) {23         this.name = name;24     }25 26     public String toString() {27         return "name:" + name;28     }29 30 }

注:由于不是标准的String类型,所以在redis控制台,用./redis-cli get myBean是看不到缓存内容的,只能得到nil的输出,不要误以为set没成功!通过代码是可以正常get到缓存值的。 

另外关于POJO对象的缓存,还有二个注意事项:

a) POJO类必须要有默认的无参构造函数,否则反序列化时会报错

b) ObjectRedisTemplate<T>中的T不能是接口,比如 DomainModelA继承自接口 IModelA,使用ObjectRedisTemplate时,要写成ObjectRedisTemplate<DomainModelA>而不是ObjectRedisTemplate<IModelA>,否则反序列化时也会出错

你可能感兴趣的文章
javascript传参字符串 与引号的嵌套调用
查看>>
进程的状态
查看>>
Runnable和Thread 两种实现方式的区别和联系:
查看>>
并发和并行的区别
查看>>
JAVA多线程和并发基础面试问答
查看>>
线程池的介绍及简单实现
查看>>
利用session,cookie进行安全性控制
查看>>
Session和Cookie的区别及Session的生命周期
查看>>
线程池 Thread Pools
查看>>
Cannot forward after response has been committed 错误解决
查看>>
Linux系统调用--getpid/getppid函数详解
查看>>
二分法排序
查看>>
内部排序
查看>>
二叉树前序、中序、后序遍历相互求法
查看>>
静态链接库与动态链接库
查看>>
C++ 子类调用父类构造和析构函数的顺序
查看>>
[进程管理]linux 下 进程和线程的区别(baidu 面试)
查看>>
父类、构造函数、成员对象的调用时机
查看>>
父类、构造函数、成员对象的调用时机
查看>>
字符串处理 子串不重复
查看>>