Spring-Boot2-X集成Redis做缓存

作者: 固安李庆海 | 来源:发表于2018-09-28 09:25 被阅读344次

    实战出真知,作文以记之。

    解决的主要痛点

    • 以SpringBoot2.0.2为背景
    • 通用的序列化和反序列化设置
      使用Jackson2JsonRedisSerializer进行序列化与反序列化。
    • 解决缓存中的乱码问题
    • 详细的使用说明
    • 齐全的使用示例

    创建Spring Boot工程

    略,详细步骤可参考使用STS创建Spring Boot 项目

    添加Maven依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </dependency>
    

    Redis的配置参数

    在application.properties中加入以下配置参数

    # 缓存时长,单位秒
    cache.default-exp=72
    # 数据库设置
    spring.redis.database=0
    # 宿主机IP
    spring.redis.host=127.0.0.1
    # 端口号
    spring.redis.port=6379
    # 密码
    spring.redis.password=redis
    # 连接超时时间 单位 ms(毫秒)
    spring.redis.timeout=3000
    # 连接池中的最大空闲连接,默认值也是8
    spring.redis.lettuce.pool.max-idle=100
    # 连接池中的最小空闲连接,默认值也是0
    spring.redis.lettuce.pool.min-idle=50
    # 如果赋值为-1,则表示不限制
    spring.redis.lettuce.pool.max-wait=2000
    

    使用注解配置Redis

    创建一个名为RedisConfig的class并继承CachingConfigurerSupport,注意需要在class上添加@Configuration和@EnableCaching注解。

    import java.lang.reflect.Method;
    import java.time.Duration;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    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.RedisSerializationContext;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import com.alibaba.fastjson.JSON;
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Value("${cache.default-exp}")
        private long exps;
    
        @Value("${spring.redis.host}")
        private String host;
    
        @Value("${spring.redis.port}")
        private int port;
    
        @Value("${spring.redis.timeout}")
        private int timeout;
    
        @Value("${spring.redis.password}")
        private String password;
    
        @Value("${spring.redis.lettuce.pool.min-idle}")
        private int minIdle;
    
        @Value("${spring.redis.lettuce.pool.max-idle}")
        private int maxIdle;
    
        @Value("${spring.redis.lettuce.pool.max-wait}")
        private long maxWaitMillis;
    
        @Bean
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuffer sb = new StringBuffer();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
        /**
         * RedisTemplate配置
         *
         * @param redisConnectionFactory
         * @return
         */
        @Bean
        public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
            // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
            Jackson2JsonRedisSerializer<JSON> serializer = new Jackson2JsonRedisSerializer<JSON>(JSON.class);
            ObjectMapper mapper = new ObjectMapper();
            mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            serializer.setObjectMapper(mapper);
            template.setValueSerializer(serializer);
            template.setHashValueSerializer(serializer);
            // 使用StringRedisSerializer来序列化和反序列化redis的key值
            template.setKeySerializer(new StringRedisSerializer());
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
            // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
            Jackson2JsonRedisSerializer<JSON> serializer = new Jackson2JsonRedisSerializer<JSON>(JSON.class);
            // 配置序列化
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));
            config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
            // 设置缓存的默认过期时间
            config.entryTtl(Duration.ofSeconds(exps));
            // 不缓存空值
            config.disableCachingNullValues();
            RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
            return cacheManager;
        }
    }
    

    缓存使用示例

    分别对@Cacheable、@CachePut和@CacheEvict进行了举例。

    @Cacheable(value = "users",key = "#collection.concat(#user.id)")
    public void create(String collection, JSONObject  user)  {
      //do something
    }
    
    @CacheEvict(value = "users",key = "#collection.concat(#id)")
    public void delete(String collection, String id)  {
      //do something
    }
    
    @Cacheable(value = "users",key = "#collection.concat(#id)")
    public JSONObject getOne(String collection, String id)  {
      //do something
    }
    

    注意事项

    • 要缓存的 Java 对象必须实现 Serializable 接口
    • 在CacheManager对象中 设置缓存过期时间,否则缓存对象将永不过期
    • 缓存key必须为string类型的值,否则需要进行类型转换

    相关文章

      网友评论

        本文标题:Spring-Boot2-X集成Redis做缓存

        本文链接:https://www.haomeiwen.com/subject/ojeuoftx.html