Springboot 2.0 - 集成redis-LMLPHP

最近在入门SpringBoot,然后在感慨 SpringBoot较于Spring真的方便多时,顺便记录下自己在集成redis时的一些想法。

1、从springboot官网查看redis的依赖包

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、操作redis

/*
   操作k-v都是字符串的
 */
@Autowired
StringRedisTemplate stringRedisTemplet;

/*
操作k-v都是对象的
*/

@Autowired
RedisTemplate redisTemplate;

redis的包中提供了两个可以操作方法,根据不同类型的值相对应选择。

两个操作方法对应的redis操作都是相同的

 stringRedisTemplet.opsForValue() // 字符串
 stringRedisTemplet.opsForList() // 列表
 stringRedisTemplet.opsForSet() // 集合
 stringRedisTemplet.opsForHash() // 哈希
 stringRedisTemplet.opsForZSet() // 有序集合

3、修改数据的存储方式

在StringRedisTemplet中,默认都是存储字符串的形式;在RedisTemplet中,值可以是某个对象,而redis默认把对象序列化后存储在redis中(所以存放的对象默认情况下需要序列化)

如果需要更改数据的存储方式,如采用json来存储在redis中,而不是以序列化后的形式。

1)自己创建一个RedisTemplate实例,在该实例中自己定义json的序列化格式(org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer)

// 这里传入的是employee对象(employee 要求可以序列化)
Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);

2)把定义的格式放进自己定义的RedisTemplate实例中

RedisTemplate<Object,Employee> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 定义格式
Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
// 放入RedisTemplate实例中
template.setDefaultSerializer(jackson2JsonRedisSerializer);

参考代码:

@Bean
 public RedisTemplate<Object,Employee> employeeRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException{
        RedisTemplate<Object,Employee> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        return template;
    }

原理:

@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }
<span class="hljs-meta">@Bean</span>
<span class="hljs-meta">@ConditionalOnMissingBean</span>(
    name = {<span class="hljs-string">"redisTemplate"</span>}
) <span class="hljs-comment">// 在容器当前没有redisTemplate时运行</span>
<span class="hljs-keyword">public</span> RedisTemplate&lt;Object, Object&gt; redisTemplate(RedisConnectionFactory redisConnectionFactory) <span class="hljs-keyword">throws</span> UnknownHostException {
    RedisTemplate&lt;Object, Object&gt; template = <span class="hljs-keyword">new</span> RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    <span class="hljs-keyword">return</span> template;
}

<span class="hljs-meta">@Bean</span>
<span class="hljs-meta">@ConditionalOnMissingBean</span> <span class="hljs-comment">// 在容器当前没有stringRedisTemplate时运行</span>
<span class="hljs-keyword">public</span> StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) <span class="hljs-keyword">throws</span> UnknownHostException {
    StringRedisTemplate template = <span class="hljs-keyword">new</span> StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    <span class="hljs-keyword">return</span> template;
}

}

如果你自己定义了RedisTemplate后并添加@Bean注解,(要在配置类中定义),那么默认的RedisTemplate就不会被添加到容器中,运行的就是自己定义的ReidsTemplate实例,而你在实例中自己定义了序列化格式,所以就会以你采用的格式定义存放在redis中的对象。

4、更改默认的缓冲

springboot默认提供基于注解的缓冲,只要在主程序类(xxxApplication)标注@EnableCaching,缓冲注解有

@Cachingable、@CachingEvict、@CachingPut,并且该缓冲默认使用的是ConcurrentHashMapCacheManager

当引入redis的starter后,容器中保存的是RedisCacheManager ,RedisCacheManager创建RedisCache作为缓冲组件,RedisCache通过操纵redis缓冲数据

5、修改redis缓冲的序列化机制

在SpringBoot中,如果要修改序列化机制,可以直接建立一个配置类,在配置类中自定义CacheManager,在CacheManager中可以自定义序列化的规则,默认的序列化规则是采用jdk的序列化

注:在SpringBoot 1.5.6 和SpringBoot 2.0.5 的版本中自定义CacheManager存在差异

参考代码:

// springboot 1.x的版本
public RedisCacheManager employeeCacheManager(RedisConnectionFactory redisConnectionFactory){
<span class="hljs-comment">// 1、自定义RedisTemplate</span>
RedisTemplate&lt;Object,Employee&gt; <span class="hljs-keyword">template</span> = <span class="hljs-keyword">new</span> RedisTemplate&lt;&gt;();
<span class="hljs-keyword">template</span>.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer&lt;Employee&gt; jackson2JsonRedisSerializer = <span class="hljs-keyword">new</span> Jackson2JsonRedisSerializer&lt;Employee&gt;(Employee.class);
<span class="hljs-keyword">template</span>.setDefaultSerializer(jackson2JsonRedisSerializer);

<span class="hljs-comment">// 2、自定义RedisCacheManager</span>
RedisCacheManager cacheManager = <span class="hljs-keyword">new</span> RedisCacheManager(<span class="hljs-keyword">template</span>);
cacheManager.setUsePrefix(<span class="hljs-literal">true</span>); <span class="hljs-comment">// 会将CacheName作为key的前缀</span>

<span class="hljs-keyword">return</span> cacheManager;

}

// springboot 2.x的版本

/**

  • serializeKeysWith() 修改key的序列化规则,这里采用的是StringRedisSerializer()
  • serializeValuesWith() 修改value的序列化规则,这里采用的是Jackson2JsonRedisSerializer<Employee>(Employee.class)
  • @param factory
  • @return
    */
    @Bean
    public RedisCacheManager employeeCacheManager(RedisConnectionFactory redisConnectionFactory)
    {

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<Employee>(Employee.class)));

    RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();

    <span class="hljs-keyword">return</span> cacheManager;
}</code></pre>

tip:可以通过查看各版本的org.springframework.data.redis.cache.RedisCacheConfiguration去自定义CacheManager.

因为不同版本的SpringBoot对应的Redis版本也是不同的,所以要重写时可以查看官方是怎么定义CacheManager,才知道怎样去自定义CacheManager。

10-04 19:30