笔者使用的版本为:spring-data-redis-2.2.2.RELEASE.jar
原始redis操作实现步骤:
RedisTemplate也基本是按照这个步骤来实现的,只是将共有方法抽象出来
RedisTemplate的实现步骤:
首先创建redis-config.properties文件:
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=100
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=5
# 连接超时时间(毫秒)
spring.redis.timeout=1000000
# 最大连接数
spring.redis.pool.max-total=200
创建RedisConfig类:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@PropertySource(value = { "classpath:redis-config.properties" })
public class RedisConfig {
/**
* 连接池配置信息
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.redis.pool")
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
/**
* 2.创建RedisConnectionFactory:配置redis 链接信息
*/
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig config) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcf = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration
.builder();
// 修改我们的连接池配置
jpcf.poolConfig(config);
// 通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcf.build();
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
/**
* RedisTemplate(或StringRedisTemplate)虽然已经自动配置,但是不灵活(第一没有序列化,第二泛型为
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
setRedisTemplate(redisTemplate);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
// JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置值(value)的序列化采用FastJsonRedisSerializer。
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
}
}
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() {
}
@Resource
RedisTemplate<String, Object> redisTemplate;
@Test
void testOne() {
redisTemplate.opsForValue().set("name", "jack");
Boolean hasKey = redisTemplate.hasKey("name");
System.out.println(hasKey);
}
}
opsForValue()方法返回的是一个ValueOperations.java
作用:操作redis数据
代码解析如下
RedisTemplate.hasKey()方法,主要内容如下:
public Boolean hasKey(K key) {
// 1.将对象类型的key转换为byte[]类型
final byte[] rawKey = rawKey(key);
// 2.执行execute方法,主要是为了获取RedisConnection,真正执行在回调方法里
return execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection) {
// 3.真正执行方法
return connection.exists(rawKey);
}
}, true);
}
execute()方法内容如下:
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
Assert.isTrue(this.initialized, "template not initialized; call afterPropertiesSet() before using it");
Assert.notNull(action, "Callback object must not be null");
// 1.获取连接池工厂,即RedisConfig类中的RedisConnectionFactory bean
RedisConnectionFactory factory = this.getRequiredConnectionFactory();
RedisConnection conn = null;
Object var11;
try {
if (enableTransactionSupport) {
// only bind resources in case of potential transaction synchronization
conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
} else {
// 2.获取连接
conn = RedisConnectionUtils.getConnection(factory);
}
boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
RedisConnection connToUse = preProcessConnection(conn, existingConnection);
boolean pipelineStatus = connToUse.isPipelined();
if (pipeline && !pipelineStatus) {
connToUse.openPipeline();
}
RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
// 3.封装连接后,将连接传入回调函数,然后执行真正的操作
T result = action.doInRedis(connToExpose);
// close pipeline
if (pipeline && !pipelineStatus) {
connToUse.closePipeline();
}
// TODO: any other connection processing?
return postProcessResult(result, connToUse, existingConnection);
} finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
}
下面对execute()方法逐步解析
@Nullable
private RedisConnectionFactory connectionFactory;
...
@Nullable
public RedisConnectionFactory getConnectionFactory() {
return this.connectionFactory;
}
获取工厂这一步,直接从RedisAccessor类中获取,RedisTemplate类继承了RedisAccessorpublic static RedisConnection doGetConnection(RedisConnectionFactory factory, boolean allowCreate, boolean bind,
boolean enableTransactionSupport) {
...
// 获得连接操作
RedisConnection conn = factory.getConnection();
...
return conn;
}
具体实现在JedisConnectionFactory.getConnection()中:public RedisConnection getConnection() {
if (cluster != null) {
return getClusterConnection();
}
Jedis jedis = fetchJedisConnector();
// 主要操作
JedisConnection connection = (usePool ? new JedisConnection(jedis, pool, dbIndex, clientName)
: new JedisConnection(jedis, null, dbIndex, clientName));
connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
return postProcessConnection(connection);
}
JedisConnection封装了Jedis、Pool等域public Boolean hasKey(K key) {
// 1.将对象类型的key转换为byte[]类型
final byte[] rawKey = rawKey(key);
// 2.执行execute方法,主要是为了获取RedisConnection,真正执行在回调方法里
return execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection) {
// 3.真正执行方法
return connection.exists(rawKey);
}
}, true);
}
真正执行的为connection.exists方法,具体实现类为JedisConnection,方法内容如下:public Boolean exists(byte[] key) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.exists(key)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.exists(key)));
return null;
}
// 执行方法
return jedis.exists(key);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}