本人初次使用Redis时,对Spring Data Redis的使用比较疑惑:
为什么既有RedisTemplate类又有ListOperations这些类?
对此,我用我所学不多的知识和粗陋的看源码的能力去自己看看源码,得出了一点拙见
如有错误,欢迎指正!
java使用redis有两种方法
一种是Jedis,比较原生
另一种是RedisTemplate,是封装后的类
两者的关系就像是jdbc和jdbcTemplate之间的关系,一个是原生的,另一个是被封装的
1.Jedis
由于Jedis的使用比较简单,如果有jdbc的基础的话肯定很容易理解
先导依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.3</version>
</dependency>
直接上示例代码
public static void main(String[] args) {
// 建立连接
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println("Connection to redis server successfully");
// 测试连接
System.out.println("redis server is running:" + jedis.ping());
jedis.set("username", "zhangsan");
String username = jedis.get("username");
System.out.println(username);
Map<String, String> map = new HashMap<>();
map.put("age", "12");
jedis.hset("user", map);
String age = jedis.hget("user", "age");
Map<String, String> redisMap = jedis.hgetAll("user");
System.out.println(age);
System.out.println(redisMap);
}
2.RedisTemplate
对于RedisTemplate的使用,网上有很多教程,我就不赘述了,我直入主题,请看VCR!
由于Redis有很多种数据结构,我以列表l的操作类ListOperations为例进行探究
首先就是两个类,一个类是RedisTemplate, 一个类是ListOperations
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Resource(name="redisTemplate")
private ListOperations<String, String>listOps;
那用哪个类对redis-server进行操作呢,另一个类又有什么用呢
让我们进入RedisTemplate.java的源码
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
...
private final ListOperations<K, V> listOps = new DefaultListOperations<>(this);
...
public ListOperations<K, V> opsForList() {
return listOps;
}
...
}
进入RedisTemplate.java的源码后,我们可以看到有一个方法opsForList()
这个opsForList()方法返回的是ListOperations类,那这个ListOperations不就是列表的操作类吗,并且RedisTemplate类也实例化了ListOperations类,并且还用opsForList方法返回了,那不就说明redisTemplate.opsForList()就是给我们创建一个ListOperations类
但是
private final ListOperations<K, V> listOps = new DefaultListOperations<>(this);
这行代码什么意思呢?哪冒出的DefaultListOperations呢?(大胆假设,接口的实现类)
让我们进入ListOperations.java源码
public interface ListOperations<K, V> {
...
}
class DefaultListOperations<K, V> extends AbstractOperations<K, V> implements ListOperations<K, V> {
DefaultListOperations(RedisTemplate<K, V> template) {
super(template);
}
...
}
首当其冲就是interface ListOperations,原来ListOperations是一个接口,
那我们看ListOperations的实现类
DefaultListOperations!!!
并且他的构造函数的参数还是RedisTemplate类型的,对应了之前的 new DefaultListOperations<>(this) 中的this
再联想到RedisTemplate中有各种xxxOperations的实例化,这一切就都水落石出了。
xxxOperations是一个用来操作的类,而RedisTemplate是一个用来实例化操作类的类
所以,我们不仅能用这种方式获取操作类
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Resource(name="redisTemplate")
private ListOperations<String, String>listOps;
也可以用这种方式获取操作类
@Autowired
private RedisTemplate<String, String> redisTemplate;
ListOperations<String, String> listOperations = redisTemplate.opsForList();
当然,我想,事实上,上面那种获取方式的底层也就是下面这种获取方式,只是spring容器自动帮我们调用了