Redis-03(整合springboot)
SpringBoot整合
springboot操作数据:springdata jpa jdbc mongodb redis
Springdata也是和SpringBoot齐名的项目
源码分析
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
// 我们可以自己定义一个redisTemplate来替换这个默认的!
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
// 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 <String, Object>
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean // 由于 String 是redis中最常使用的类型,所以说单独提出来了一个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
整合测试
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。
jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
我们在学习SpringBoot自动配置的原理时,整合一个组件并进行配置一定会有一个自动配置类xxxAutoConfiguration,并且在spring.factories中也一定能找到这个类的完全限定名。Redis也不例外。
还存在一个RedisProperties类
@ConditionalOnClass注解中有两个类是默认不存在的,所以Jedis是无法生效的然后在看Lettuec:
生效
我们回到RedisAutoConfiguration
只有两个简单的Bean
- RedisTemplate
- StringRedisTemplate
当看到xxxTemplate时可以对比RestTemplate,SqlSessionTemplate通过使用这些Template来简介操作组件,这两个也不例外,分别用于操作Redis和Redis中的String数据类型.
在RedisTemplate上也有一个条件注解,说明我们是可以对其定制化的
我们需要知道如何编写配置文件然后连接Redis,就需要阅读RedisProperties
- 编写配置文件application.xml中配置
# 配置redis
spring.redis.host=39.99.xxx.xx
spring.redis.port=6379
- 使用RedisTemplate(新建一个config.RedisConfig.java)
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//在企业开发中,80%都不会使用原生的方式编写代码,我们可以使用RedisUtils去编写代码
//opsForValue:操作字符串,类似于String
//opsForList:操作List,类似于List
//opsForSet:操作set,类似于set
//opsForHash:操作hash,类似于hash
//opsForZset:操作zset,类似于zset
//opsForGeo:操作geo,类似于geo
//...
//除了基本的操作,常用的方法都可以直接通过redisTemplate操作,比如事务和CRUD
//RedisConfig.flushDb();
redisTemplate.opsForValue().set("key","sli");
System.out.println(redisTemplate.opsForValue().get("key"));
}
- 测试结果,回到Redis客户端查看数据的时候发现都是乱码,是由于没有序列化造成的,RedisTemplate内部的序列化配置是这样的
默认的序列化器采用JDK序列化器
后续我们定制RedisTemplate就可以对其进行修改。
RedisSerializer提供了多种序列化方案:
我们自己编写RedisTemplate来使原来的失效
package com.sli.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
// 固定模板在企业中,拿去就可以直接使用!
// 自己定义了一个 RedisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 为了开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String,
Object>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
- 编写测试代码
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
@Test
public void test(){
User user = new User("sli", 2);
redisTemplate.opsForValue().set("user",user);
System.out.println(redisTemplate.opsForValue().get("user"));
}
- 通过这样的序列化之后key就不会乱码了,但是在企业中开发一般不直接写原生的代码,将常用的操作封装为RedisUtils,自己写一些工具类来调用,工具类中能加入一些容错操作,抛出异常.