Spring、SpringBoot整合Redis
# Spring、SpringBoot整合Redis
无论是Spring、还是SpringBoot整合Redis,其实主要套路都是一样的:
- 引入依赖(pom),数据源配置(Bean/xml,RedisConnectionFactory),使用API。
只是相对的SpringBoot约定优于配置,相比Spring简化了更多配置。
这里会列举部分配置样板,这些都可以从官方文档找到,更具体的配置,翻阅官方文档就可以了,同时讲讲API使用的注意事项。
- 配置样板是配置Redis单例的,主从、集群的配置翻阅官方文档。
# Spring整合Redis
# 引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.6.3</version>
</dependency>
<!-- 有两种客户端选择,二选一 Lettuce(默认) and Jedis-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.1</version>
</dependency>
</dependencies>
# 数据源配置
配置文件properties
格式参考
redis.pool.maxActive=100
redis.pool.maxIdle=50
redis.pool.maxWait=1000
redis.pool.testOnBorrow=true
redis.timeout=50000
redis.server=127.0.0.1
redis.port=6379
xml配置JedisConnectionFactory
、jedisPoolConfig
参考:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!-- redis config 这里是使用了jedis客户端 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="${redis.pool.maxActive}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxWait" value="${redis.pool.maxWait}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.server}"/>
<property name="port" value="${redis.port}"/>
<property name="timeout" value="${redis.timeout}" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="KeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
<property name="ValueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
</bean>
</beans>
Bean 配置JedisConnectionFactory
方式参考
@Configuration
class AppConfig {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
return new JedisConnectionFactory();
}
}
# SpringBoot整合Redis
# 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
# 数据源配置
配置文件yml
格式参考:
spring:
redis:
host: 127.0.0.1
port: 6379
jedis:
pool:
min-idle: 0
max-idle: 8
max-active: 80
max-wait: 30000
timeout: 3000
SpringBoot配置完成配置文件后,直接就可以使用了,默认给我们配置了RedisConnectionFactory
。
# API的使用
Spring 把对Redis 的操作都封装在 spring-data-redis 。
# high-level & low-level
The Redis support provides several components. For most tasks, the high-level abstractions and support services are the best choice. Note that, at any point, you can move between layers. For example, you can get a low-level connection (or even the native library) to communicate directly with Redis.
官方的大概意思是spring-data-redis
主要提供了两类API,high-level
API 能满足大多数情况下的业务场景,而 low-level
则是一更底层的连接与 Redis 通信。
以操作 string 数据类型为例(部分代码):
// @Autowired RedisTemplate redisTemplate;
// high-level
stringRedisTemplate.opsForValue().set("k1", "hello");
// low-level
RedisConnection conn = redisTemplate.getConnectionFactory().getConnection();
conn.set("k1".getBytes(), "hello".getBytes());
high-level显然使用起来更加方便,将设置k-v、使用连接等操作都封装了起来。
两者在获取“k1”的value是相同的,但是如果你去查看Redis数据库,两者存储起来的k-v在二进制数据有区别
- opsForValue().set方式存储的key-value的数据前面多了一些“乱码”,例如key变成"xxxxXXXXxxxxk1"
- conn.set方式存储的key-value则正常。
这是因为redis是二进制安全的,high-level的API如果采用默认的序列化,默认走的是java的序列化,所以会加上一些附加信息。
# 序列化
由于redis是二进制安全,通常我们在使用API的时候,建议制定序列化规则,这样我们存储在Redis的数据会尽量“干净”。
通常,我们可以自定义RedisTemplate,如下:
@Configuration
public class RedisConfig {
@Autowired
RedisConnectionFactory factory;
@Bean
public RedisTemplate<String, Object> redisTemplate(){
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public StringRedisTemplate strRedisTemplateX(RedisConnectionFactory fc){
StringRedisTemplate tp = new StringRedisTemplate(fc);
tp.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
return tp ;
}
......
}
接下来用上面自定义的strRedisTemplateX,操作hash数据类型,存储一个POJO为例(部分代码):
// @Autowired @Qualifier("strRedisTemplateX") StringRedisTemplate strRedisTemplateX;
User usr = new User("zhangsan", "20");
Jackson2HashMapper jhm = new Jackson2HashMapper(objectMapper, false);
strRedisTemplateX.opsForHash().putAll("pojo", jhm.toHash(usr));