RedisTemplate 是spring集成的redis上层操作模版,底层集成了很多redis 的API,今天开始我们从源码的角度依次分析每个API接口的功能。
首先分析 RedisTemplate类:如下图
1、六种类型的API接口
private @Nullable ValueOperations<K, V> valueOps;
private @Nullable ListOperations<K, V> listOps;
private @Nullable SetOperations<K, V> setOps;
private @Nullable ZSetOperations<K, V> zSetOps;
private @Nullable GeoOperations<K, V> geoOps;
private @Nullable HyperLogLogOperations<K, V> hllOps;
1、取到数据源-opsForValue
@Override
public ValueOperations<K, V> opsForValue() {
if (valueOps == null) {
valueOps = new DefaultValueOperations<>(this);
}
return valueOps;
}
2、点击 DefaultValueOperations 类名,进入后显示其下所有API:
3、分析每个接口详情:
class DefaultValueOperations<K, V> extends AbstractOperations<K, V> implements ValueOperations<K, V> {
DefaultValueOperations(RedisTemplate<K, V> template) {
super(template);
}
/*
* 获取key键对应的值。
*/
@Override
public V get(Object key) {
return execute(new ValueDeserializingRedisCallback(key) {
@Override
protected byte[] inRedis(byte[] rawKey, RedisConnection connection) {
return connection.get(rawKey);
}
}, true);
}
/*
* 获取原来key键对应的值并重新赋新值
*/
@Override
public V getAndSet(K key, V newValue) {
byte[] rawValue = rawValue(newValue);
return execute(new ValueDeserializingRedisCallback(key) {
@Override
protected byte[] inRedis(byte[] rawKey, RedisConnection connection) {
return connection.getSet(rawKey, rawValue);
}
}, true);
}
/*
* 以增量的方式将值存储在变量中。
*/
@Override
public Long increment(K key) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.incr(rawKey), true);
}
/*
* 以增量的方式将long值存储在变量中。
*/
@Override
public Long increment(K key, long delta) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.incrBy(rawKey, delta), true);
}
/*
* 以增量的方式将double值存储在变量中
*/
@Override
public Double increment(K key, double delta) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.incrBy(rawKey, delta), true);
}
/*
* 以减量的方式将值存储在变量中。
*/
@Override
public Long decrement(K key) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.decr(rawKey), true);
}
/*
* 以减量的方式将long值存储在变量中
*/
@Override
public Long decrement(K key, long delta) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.decrBy(rawKey, delta), true);
}
/*
* 在原有的值基础上新增字符串到末尾
*/
@Override
public Integer append(K key, String value) {
byte[] rawKey = rawKey(key);
byte[] rawString = rawString(value);
return execute(connection -> {
Long result = connection.append(rawKey, rawString);
return (result != null) ? result.intValue() : null;
}, true);
}
/*
* 截取key键对应值得字符串,从开始下标位置开始到结束下标的位置(包含结束下标)的字符串
*/
@Override
public String get(K key, long start, long end) {
byte[] rawKey = rawKey(key);
byte[] rawReturn = execute(connection -> connection.getRange(rawKey, start, end), true);
return deserializeString(rawReturn);
}
/*
* 根据集合取出对应的value值
*/
@Override
public List<V> multiGet(Collection<K> keys) {
if (keys.isEmpty()) {
return Collections.emptyList();
}
byte[][] rawKeys = new byte[keys.size()][];
int counter = 0;
for (K hashKey : keys) {
rawKeys[counter++] = rawKey(hashKey);
}
List<byte[]> rawValues = execute(connection -> connection.mGet(rawKeys), true);
return deserializeValues(rawValues);
}
/*
* 设置map集合到redis
*/
@Override
public void multiSet(Map<? extends K, ? extends V> m) {
if (m.isEmpty()) {
return;
}
Map<byte[], byte[]> rawKeys = new LinkedHashMap<>(m.size());
for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
rawKeys.put(rawKey(entry.getKey()), rawValue(entry.getValue()));
}
execute(connection -> {
connection.mSet(rawKeys);
return null;
}, true);
}
/*
* 如果对应的map集合名称不存在,则添加,如果存在则不做修改
*/
@Override
public Boolean multiSetIfAbsent(Map<? extends K, ? extends V> m) {
if (m.isEmpty()) {
return true;
}
Map<byte[], byte[]> rawKeys = new LinkedHashMap<>(m.size());
for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
rawKeys.put(rawKey(entry.getKey()), rawValue(entry.getValue()));
}
return execute(connection -> connection.mSetNX(rawKeys), true);
}
/*
* 新增一个字符串类型的值,key是键,value是值
*/
@Override
public void set(K key, V value) {
byte[] rawValue = rawValue(value);
execute(new ValueDeserializingRedisCallback(key) {
@Override
protected byte[] inRedis(byte[] rawKey, RedisConnection connection) {
connection.set(rawKey, rawValue);
return null;
}
}, true);
}
/*
* 设置变量值的过期时间
*/
@Override
public void set(K key, V value, long timeout, TimeUnit unit) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
potentiallyUsePsetEx(connection);
return null;
}
public void potentiallyUsePsetEx(RedisConnection connection) {
if (!TimeUnit.MILLISECONDS.equals(unit) || !failsafeInvokePsetEx(connection)) {
connection.setEx(rawKey, TimeoutUtils.toSeconds(timeout, unit), rawValue);
}
}
private boolean failsafeInvokePsetEx(RedisConnection connection) {
boolean failed = false;
try {
connection.pSetEx(rawKey, timeout, rawValue);
} catch (UnsupportedOperationException e) {
// in case the connection does not support pSetEx return false to allow fallback to other operation.
failed = true;
}
return !failed;
}
}, true);
}
/*
* 如果键不存在则新增,存在则不改变已经有的值
*/
@Override
public Boolean setIfAbsent(K key, V value) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
return execute(connection -> connection.setNX(rawKey, rawValue), true);
}
/*
* 如果键不存在则新增,存在则不改变已经有的值,加上过期时间
*/
@Override
public Boolean setIfAbsent(K key, V value, long timeout, TimeUnit unit) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
Expiration expiration = Expiration.from(timeout, unit);
return execute(connection -> connection.set(rawKey, rawValue, expiration, SetOption.ifAbsent()), true);
}
/*
* 判断当前的键的值是否为v,是的话不作操作,不是的话进行替换。
如果没有这个键也不会做任何操作。
*/
@Nullable
@Override
public Boolean setIfPresent(K key, V value) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
return execute(connection -> connection.set(rawKey, rawValue, Expiration.persistent(), SetOption.ifPresent()), true);
}
/*
* 判断当前的键的值是否为v,是的话不作操作,不是的话进行替换,加上超时时间。
如果没有这个键也不会做任何操作。
*/
@Nullable
@Override
public Boolean setIfPresent(K key, V value, long timeout, TimeUnit unit) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
Expiration expiration = Expiration.from(timeout, unit);
return execute(connection -> connection.set(rawKey, rawValue, expiration, SetOption.ifPresent()), true);
}
/*
* 保存值,然后加上过期时间
*/
@Override
public void set(K key, V value, long offset) {
byte[] rawKey = rawKey(key);
byte[] rawValue = rawValue(value);
execute(connection -> {
connection.setRange(rawKey, rawValue, offset);
return null;
}, true);
}
/*
* 获取指定字符串的长度
*/
@Override
public Long size(K key) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.strLen(rawKey), true);
}
/*
* key键对应的值value对应的ascii码,在offset的位置(从左向右数)变为value
*/
@Override
public Boolean setBit(K key, long offset, boolean value) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.setBit(rawKey, offset, value), true);
}
/*
* 判断指定的位置ASCII码的bit位是否为 offset
*/
@Override
public Boolean getBit(K key, long offset) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.getBit(rawKey, offset), true);
}
/*
* 和布隆过滤器相关,后期会详细分析,参考:https://blog.csdn.net/nandao158/article/details/121910247
*/
@Override
public List<Long> bitField(K key, final BitFieldSubCommands subCommands) {
byte[] rawKey = rawKey(key);
return execute(connection -> connection.bitField(rawKey, subCommands), true);
}
}
到此,RedisTemplate源码详解-opsForValue到此结束,使用参考
下篇分享RedisTemplate源码详解-opsForList 敬请期待!