1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
源码分析 在Spring2.x之后,使用的就不再是redis了,而是lettuce
- jedis 直连,多线程不安全,通过jedis pool 线程池避免,像bio模式
- lettuce 采用netty多路复用异步非阻塞的连接,像nio模式 点击这个spring-boot-starter-data-redis依赖包我们可以看到
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.0.4.RELEASE</version>
<scope>compile</scope>
</dependency>
说明是通过lettuce实现的
public class RedisAutoConfiguration {
@Bean
//当没有redisTemplate的时候才生效
@ConditionalOnMissingBean(name = "redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的redisTemplate没有进行过多的操作,而我们的redis对象却是需要序列化的
//因而需要自定义reisTemplate
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
2. 配置属性
# 更多属性配置在RedisProperties类中查看
spring.redis.host= 192.168.252.128
spring.redis.port= 6379
3. 整合测试
class DemoApplicationTests {
@Autowired
RedisTemplate redisTemplate=new RedisTemplate();
@Test
void contextLoads() {
// redisTemplate 操作类似于redis的指令
// opsForValue 操作字符串,类似String
// opsForList 操作List
redisTemplate.opsForValue().set("user","lin");
// 尽管在java中成功获取了对象但是由于没有序列化在redis服务器中会存在乱码
System.out.println(redisTemplate.opsForValue().get("user"));
// 获取连接对象
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushAll();
connection.flushDb();
}
}
4. 自定义Template
而当我们序列化之后,尽管在控制台可以正常的获取对象但是在服务器中却是
因此我们需要自行设置序列化
@Configuration
public class RedisConfig {
@Bean
// 由于主要使用String做key所以直接定义为String
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
//自定义序列化方案
//配置String序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//配置Json序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om=new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 原 enableDefaultTyping() 已过期
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//key 使用string序列化
template.setKeySerializer(stringRedisSerializer);
//hashkey 使用string序列化
template.setHashKeySerializer(stringRedisSerializer);
// value 使用jason序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash value使用jason序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
现在我们再测试一下
@SpringBootTest
class DemoApplicationTests {
@Resource(name = "redisTemplate") //由于有默认的RedisTemplate所以我们需要通过name来匹配
RedisTemplate redisTemplate=new RedisTemplate();
@Test
void contextLoads() {
User lin = new User("lin", 18);
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
redisTemplate.opsForValue().set("user1",lin);
System.out.println(redisTemplate.opsForValue().get("user1"));
connection.close();
}
}