Spring boot 中配置 redis 作为缓存

redis 安装请参考 此文

1. 引入依赖

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

2. application.yml 配置文件中增加配置

spring:
    redis:
        # Redis数据库索引(默认为0)
        database: 0 
        # Redis服务器地址
        host: 10.150.1.71
        # Redis服务器连接端口
        port: 6379
        # Redis服务器连接密码(默认为空)
        #password: 
        pool: 
            # 连接池最大连接数(使用负值表示没有限制)
            max-active: -1
            # 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-wait: -1
            # 连接池中的最大空闲连接
            max-idle: 8
            # 连接池中的最小空闲连接
            min-idle: 0
        # 连接超时时间(毫秒)
        timeout: 15000

此处插一句嘴:在redis服务器的配置文件中,bind 属性绑定的IP,是指 redis 服务器对外暴露的IP,也就是其他应用需要用这个IP才能访问redis服务器

3. 程序主入口添加 @EnableCaching 注解

@SpringBootApplication(scanBasePackages = {"com.test"})
@ServletComponentScan
@EnableScheduling
@EnableCaching
public class Application {

    private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
    
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
        LOGGER.info("applicatin sso started!");
    }
    
}

至此 spring boot redis 配置缓存已经结束,使用 spring boot 提供的方法 @Cacheable  @CachePut 等即可进行缓存操作。


以下内容为实际项目中遇到的问题记录。

1. @Cacheable(value="a", key="b") 与 @Cacheable(cacheNames="a", key="b") 是等价的,因为 cacheNames 是 value 的一个别名。

2. 在不做任何自定义配置的情况下,你会发现 redis 中存储的 key 带有序列化的数据,比如

\xac\xed\x00\x05t\x00a

这样,根本原因是 spring boot 采用的 key 默认序列化的方式为 JdkSerializationRedisSerializer,解决方法就是自己写配置进行序列化

package com.test.sso.in;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Redis缓存配置类
 *
 * @author walli
 *
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    
    // 缓存失效时间,单位 秒
    private static final long DEFAULT_CACHE_EXPIRE_TIME = 1800L;

    //自定义缓存key生成策略
//    @Bean
//    public KeyGenerator keyGenerator() {
//        return new KeyGenerator(){
//            @Override
//            public Object generate(Object target, java.lang.reflect.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();
//            }
//        };
//    }
    //缓存管理器
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间 
        cacheManager.setDefaultExpiration(DEFAULT_CACHE_EXPIRE_TIME);
        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        //设置序列化工具
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        template.setKeySerializer(redisSerializer);  
        template.setHashKeySerializer(redisSerializer);  
        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);  
        template.setValueSerializer(jackson2JsonRedisSerializer);  
        template.setHashValueSerializer(jackson2JsonRedisSerializer); 
        
        template.afterPropertiesSet();
        return template;
    }
}

3. 经过上述配置之后,在 redis-cli 中输入 keys * 你会发现没有序列化的乱码了,但是目标的 key 与自己的预想并不一致,你会发现如果你配置的缓存为 @Cacheable(cacheNames="a", key="b"),redis 中实际存储的数据 key 会有两个,一个是 b, 另一个是 a~keys。其实这个是 spring boot 缓存实现方式的问题,b 即为你实际所需的缓存 key,而 a~keys 的类型为 ZSET,其中保存了所有的 cacheNames=a 的 keys。因此如果需要直接从redis中读取缓存值,直接使用 key=b 来读取就行了。



猜你喜欢

转载自blog.csdn.net/zxcvqwer19900720/article/details/79861703