Redis之整合SpringBoot
redis官方对Java语言的封装框架推荐有十多种,主要有:Jedis、Lettuce、Redisson
1几个框架的对比
三个框架都是在Java中对Redis操作的封装。
1.1 Jedis
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持。支持基本的数据类型如:String、Hash、List、Set、Sorted Set。
优点:比较全面的提供了Redis的操作特性,相比于其他Redis 封装框架更加原生。
编程模型: 使用阻塞的I/O,方法调用同步,程序流需要等到socket处理完I/O才能执行,不支持异步操作。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。
1.2 Lettuce
高级Redis客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。
优点:适合分布式缓存框架。
编程模型:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作(springboot2.0之后,redis的conn已经由jedis更改为lettuce)。
1.3 Redisson
Redisson实现了分布式和可扩展的Java数据结构。Redisson不仅提供了一系列的分布式Java常用对象,基本可以与Java的基本数据结构通用,还提供了许多分布式服务,其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)
优点: 促使使用者对Redis的关注分离,让使用者能够将精力更集中地放在处理业务逻辑上,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列。
第三方框架整合:
- Redisson提供了和Spring框架的各项特性类似的,以Spring XML的命名空间的方式配置RedissonClient实例和它所支持的所有对象和服务
- Redisson在Redis的基础上实现了Java缓存标准规范,并完整的实现了Spring框架里的缓存机制
- Redisson提供了Spring Session会话管理器的实现
编程模型:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作。
RedisTemplate是Spring框架对Jedis和Lettuce的封装,让Spring框架体系能够更加方便的接入Redis的功能。RedisTemplate 同时支持 Jedis和Lettuce
一、Jedis
①pom.xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
②applicaton.properties
#redis服务器地址
jedis.pool.host=192.168.124.128
#redis服务器端口
jedis.pool.port=6379
#redis的auth密码
jedis.pool.password=123456
#连接池最大连接数(使用负值表示没有限制)
jedis.pool.config.maxTotal=60
# 连接池最大阻塞等待时间(使用负值表示没有限制)
jedis.pool.config.maxWait=100
#最大空闲连接
jedis.pool.config.maxIdle=50
#最小空闲连接
jedis.pool.config.minIdle=0
③JedisConfig
package com.yj.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
@Configuration
public class JedisConfig {
@Bean(name = "jedis.pool")
@Autowired
public JedisPool jedisPool(@Qualifier("jedis.pool.config") JedisPoolConfig config,
@Value("${jedis.pool.host}") String host, @Value("${jedis.pool.port}") int port,
@Value("${jedis.pool.password}") String password) {
return new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, password);
}
@Bean(name = "jedis.pool.config")
public JedisPoolConfig jedisPoolConfig(@Value("${jedis.pool.config.maxTotal}") int maxTotal,
@Value("${jedis.pool.config.maxWait}") int maxWait,
@Value("${jedis.pool.config.maxIdle}") int maxIdle,@Value("${jedis.pool.config.minIdle}") int minIdle) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxWaitMillis(maxWait);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
return config;
}
}
二、JedisCluster
①pom.xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
②application.properties
# Redis服务器地址
spring.redis.cluster.nodes=192.168.124.128:7000,192.168.124.128:7001,192.168.124.128:7002,192.168.124.128:7006,192.168.124.129:7003,192.168.124.129:7004,192.168.124.129:7005,192.168.124.129:7007
# Redis服务器密码
spring.redis.cluster.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=60
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=100
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=50
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=200
③JedisClusterConfig
package com.yj.config;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class JedisClusterConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.password:}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-wait}")
private long maxWaitMillis;
@Value("${spring.redis.commandTimeout:5000}")
private int commandTimeout;
@Value("${spring.redis.socketTimeout:1000}")
private int socketTimeout;
@Value("${spring.redis.maxAttempts:1000}")
private int maxAttempts;
@Bean
public JedisCluster getJedisCluster() {
String[] cNodes = clusterNodes.split(",");
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
for(String node : cNodes) {
String[] hp = node.split(":");
nodes.add(new HostAndPort(hp[0],Integer.parseInt(hp[1])));
}
JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setMaxTotal(maxActive);
if (StringUtils.isEmpty(password)) {
return new JedisCluster(nodes, commandTimeout, jedisPoolConfig);
}
return new JedisCluster(nodes, commandTimeout, socketTimeout, maxAttempts, password, jedisPoolConfig);
}
}
三、RedisTemple
分为RedisTemple和StringRedisTemple
①pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.16</version>
</dependency>
②application.properties
# Redis服务器地址
spring.redis.hostName=192.168.124.128
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码
spring.redis.password=123456
# Redis数据库索引(默认为0)
spring.redis.database=0
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=60
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=100
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=50
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=200
③RedisTemplateConfig
package com.yj.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class RedisTemplateConfig {
private Logger logger = LoggerFactory.getLogger(RedisTemplateConfig.class);
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisConnectionFactory getConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
JedisPoolConfig config = getRedisConfig();
factory.setPoolConfig(config);
logger.info("JedisConnectionFactory bean init success");
return factory;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
使用
package com.yj;
import java.util.Date;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yj.entity.User;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
public class RedisClientTest extends ApplicationTest {
private Logger logger = LoggerFactory.getLogger(ClientTest.class);
@Autowired
private JedisPool jedisPool;
@Autowired
private JedisCluster jedisCluster;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
@Test
public void testJedis() {
Jedis jedis = jedisPool.getResource();
jedis.set("Jedis", JSON.toJSONString(getUser()));
String userStr = jedis.get("Jedis");
User value = JSONObject.parseObject(userStr, User.class);
logger.info("Jedis:" + value);
}
@Test
public void testJedisCluster() {
jedisCluster.set("JedisCluster", JSON.toJSONString(getUser()));
String userStr = jedisCluster.get("JedisCluster");
User value = JSONObject.parseObject(userStr, User.class);
logger.info("JedisCluster:" + value);
}
@Test /* 模板Bean已经配置了序列化和反序列化的策略 */
public void testRedisTemplate() {
redisTemplate.opsForValue().set("redisTemplate", getUser());
User value = (User) redisTemplate.opsForValue().get("redisTemplate");
logger.info("RedisTemplate:" + value);
}
@Test
public void testStringRedisTemplate() {
stringRedisTemplate.opsForValue().set("StringRedisTemplate", JSON.toJSONString(getUser()));
String value = stringRedisTemplate.opsForValue().get("StringRedisTemplate");
logger.info("StringRedisTemplate:" + value);
}
private User getUser() {
User user = new User();
user.setName("yj");
user.setAge(18);
user.setDate(new Date());
return user;
}
}
还没有评论,来说两句吧...