SpringBoot整合
创建springboot项目时勾选上
其在pom文件中会引入一个redis的有关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
其低层依赖为
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.2.6.RELEASE</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
我们会发现在springBoot2.x之后,原来使用的jedis被替换成了letture
比较
- jedis:采用的直连,多个线程操作的话是不安全的,如果想要避免不安全,使用jedis pool连接池。但这样带出来的问题也很多,如线程数量太多,redis的服务又太大,比较麻烦有点类似于BIO阻塞的
- letture:采用netty(高性能的网络框架,异步请求非常快),实例可以在多个线程中进行共享,不存在线程不安全的情况下,可以减少线程数据了,更像nio模式非阻塞
在springboot中的spring.factories中查找redis
点进去我们可以找到redis的相关配置类然后查看配置属性
源码分析:
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(name = {"redisTemplate"}) //该注解为当没有该name的bean时当前bean生效,否则将由你写的bean覆盖该方法
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//默认的redisTemplate没有过多的设置,redis对象都是需要序列化的
//两个泛型都是Object类型,我们可以修改一个使用<String,Object>的
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean //由于string是redis是最常用的类型,所以单独提出来了
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>
-
配置连接
-
测试
@SpringBootTest
class SpringbootRedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
}
@Test
public void test(){
User user = new User("李立杰", 3);
redisTemplate.opsForValue().set("user", user);
System.out.println(redisTemplate.opsForValue().get("user"));
}
}
具体数据类型的操作可以查看RedisTemplate中的方法
此时我们运行程序后获取该值发现存的中文获取的有问题,这是序列化的原因。
其中获取连接对象的操作:
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
connection.flushAll();
查看源码会发现
解决方案,创建一个自己的template实现json序列化
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException{
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//Json序列化配置
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化jackson的序列化方式
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}