SpringBoot使用Redis实现缓存

目录

实现步骤

1. 在 pom.xml 配置文件中添加如下依赖

2. 在 application.properties 中添加如下配置

3. 新建 RedisConfig.class,继承 CachingConfigurerSupport,添加如下方法

4. 新建 RedisService.class 添加如下方法

注意:cacheKeyGenerator 是注入的 bean,实现类如下

5. 测试一下

注意


上一章已经介绍了如何在 SpringBoot 中如何使用缓存,本章将介绍如何将缓存和 Redis 结合使用

实现步骤

1. 在 pom.xml 配置文件中添加如下依赖


    org.springframework.boot
    spring-boot-starter-data-redis

2. 在 application.properties 中添加如下配置

############################## redis 配置 ##############################
spring.redis.url = redis://localhost:6379
# 连接池最大活动连接数
spring.redis.lettuce.pool.max-active = 10
# 连接池中最小空闲连接数
spring.redis.lettuce.pool.min-idle = 5
# 最大连接等待时间
spring.redis.lettuce.pool.max-wait = 10ms

3. 新建 RedisConfig.class,继承 CachingConfigurerSupport,添加如下方法

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    /**
     * RedisTemplate 序列化配置
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        template.setKeySerializer(keySerializer);
        template.setHashKeySerializer(keySerializer);
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 注册缓存管理器
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 设置缓存 20 秒过期时间
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofSeconds(20))
            .disableCachingNullValues();
        return RedisCacheManager.builder(factory).cacheDefaults(config).transactionAware().build();
    }
}

4. 新建 RedisService.class 添加如下方法

@Service
@CacheConfig(cacheNames={"test"}, keyGenerator="cacheKeyGenerator")
public class RedisService {    
    // 该注解将向缓存中添加字符串    
    @Cacheable    
    public String save1() {	
        System.out.println(new Date() + " --> 没有从缓存取值");	
        return "ramos";    
    }    
    // 该注解将向缓存中添加 user 对象    
    @Cacheable    
    public User save2() {	
        System.out.println(new Date() + " --> 没有从缓存取值");	
        return new User(1, "dufu");    
    }    
    // 该注解将会向缓存中 添加/更新 新的值    
    // 与 @Cacheable 不同的是, 如下方法中的代码都会执行    
    @CachePut    
    public String put(String value) {	
        System.out.println(new Date() + " 添加了 value --> " + value);	
        return value;   
    }    
    // 该注解将会把缓存中的值删除掉    
    // 与 @Cacheable 不同的是, 如下方法中的代码都会执行    
    @CacheEvict    
    public void delete() { 	
        System.out.println(new Date() + " 删除了 value");    
    }
}

注意:cacheKeyGenerator 是注入的 bean,实现类如下

@Component
// 自定义缓存生成 key 的方式
public class CacheKeyGenerator implements KeyGenerator {    
    // 将目标类的类名作为 key 值    
    @Override    
    public Object generate(Object target, Method method, Object... params) {	
        return target.getClass().getName() + method.getName();    
    }
}

这里明确了 key 的生成是 由类名 + 方法名 组成,因为如果设置 key 的值为固定值的话,有可能会出现转换错误,例如:假如 save1() 和 save2() 两个方法的返回值不一致,但是缓存的 key 值一样的话,可能会第一次调用 save1() 放入 { test: ramos } , 第二次调用 save2() 就会取出 Ramos(String),但是 save2() 的返回值类型是 User,这样就会出错

5. 测试一下

注意

1. 自定义的实体类要被缓存,就必须实现 IO 的 Serializable 接口

 

@Data
public class User implements Serializable {    
    private static final long serialVersionUI = 1L;
    private int id;
    private String name;
}

2. 集成缓存会与 SpringBoot 的热部署冲突,报错:class XX cannot be cast to class XX ,XX is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader

暂未找到两全其美的解决办法;只能注释掉热部署依赖


    org.springframework.boot
    spring-boot-devtools
    true

你可能感兴趣的:(#,springBoot,缓存,redis,spring,boot)