使用Spring @Cacheable自定义缓存过期时间

实现效果

原来的@Cacheable使用方式:

@Cacheable(value = "userinfo", key = "#dto.userId")

实现后的使用方式:

@Cacheable(value = "userinfo#30#m", key = "#dto.userId")

实现代码

  1. 创建一个自定义的缓存管理器,继承自RedisCacheManager
public class CustomRedisCacheManager extends RedisCacheManager {
    
    public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    /**
     * 重写createRedisCache方法
     * @param name 原来的name只是作为redis存储键名
     *             重写的name可通过"#"拼接过期时间:
     *             1. 如果没有"#"则默认不设置过期时间
     *             2. 拼接的第一个"#"后面为过期时间,第二个"#"后面为时间单位
     *             3. 时间单位的表示使用: d(天)、h(小时)、m(分钟)、s(秒), 默认为h(小时)
     * @param cacheConfig
     * @return
     */
    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        // 解析name,设置过期时间
        if (StringUtils.isNotEmpty(name) && name.contains("#")) {
            String[] split = name.split("#");

            // 缓存键名
            String cacheName = split[0];
            // "#"后第一位是时间
            int expire = Integer.parseInt(split[1]);
            // 过期时间,默认为h(小时)
            Duration duration = Duration.ofHours(expire);
            // 根据"#"后第二位字符判断过期时间的单位,设置相应的过期时间,默认时间单位是h(小时)
            if (split.length == 3) {
                switch (split[2]){
                    case "d":
                        duration = Duration.ofDays(expire);
                        break;
                    case "m":
                        duration = Duration.ofMinutes(expire);
                        break;
                    case "s":
                        duration = Duration.ofSeconds(expire);
                        break;
                    default:
                        duration = Duration.ofHours(expire);
                }
            }
            return super.createRedisCache(cacheName, cacheConfig.entryTtl(duration));
        }
        return super.createRedisCache(name, cacheConfig);
    }
}
  1. 在redis配置类中,将上面自定义的缓存管理器注册为Bean
@Configuration
@EnableCaching
public class RedisConfig {
    
    /**
     * 自定义RedisTemplate
     * 设置Redis序列化方式,默认使用的是JDKSerializer的序列化方式,效率低,所以这里设置使用FastJsonRedisSerializer
     * @param connectionFactory
     * @return
     */
    @Bean
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        // 设置redis连接(LettuceConnectionFactory实现了RedisConnectionFactory)
        redisTemplate.setConnectionFactory(connectionFactory);

        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);

        // key设置StringRedisSerializer序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // value设置FastJsonRedisSerializer序列化
        redisTemplate.setValueSerializer(serializer);

        // Hash key设置序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // Hash value设置序列化
        redisTemplate.setHashValueSerializer(serializer);

        return redisTemplate;
    }


    /**
     * 实例化自定义的缓存管理器
     * @param redisTemplate
     * @return
     */
    @Bean
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory()));
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
        return new CustomRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }
}
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
@Cacheable注解是Spring框架中用于添加缓存的注解。它可以用于方法级别,用于标记一个方法的返回值应该被缓存起来。然而,@Cacheable注解本身并不能直接设置过期时间。要设置过期时间,需要结合@CacheConfig注解和自定义RedisCacheManager来实现。 下面是一个示例,演示了如何使用@Cacheable注解添加缓存,并设置过期时间: ```java import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.CacheConfig; @CacheConfig(cacheNames = "myCache") // 设置缓存名称 public class MyService { @Cacheable(key = "#param", cacheManager = "myCacheManager") // 设置缓存的key和使用缓存管理器 public String getData(String param) { // 从数据库或其他数据源获取数据的逻辑 return "data"; } } ``` 在上面的示例中,我们使用了@CacheConfig注解来设置缓存的名称为"myCache"。然后,在getData方法上使用了@Cacheable注解来标记该方法的返回值应该被缓存起来。我们还通过key属性设置了缓存的key,这里使用了方法的参数作为key。最后,我们指定了使用缓存管理器为"myCacheManager"。 要设置缓存过期时间,我们需要自定义一个RedisCacheManager,并在其中设置过期时间。下面是一个示例: ```java import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.RedisSerializationContext; public class MyCacheManager extends RedisCacheManager { public MyCacheManager(RedisConnectionFactory connectionFactory) { super(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory), RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())) .entryTtl(Duration.ofMinutes(10))); // 设置过期时间为10分钟 } } ``` 在上面的示例中,我们自定义了一个MyCacheManager类,继承自RedisCacheManager。在构造方法中,我们通过RedisCacheWriter和RedisCacheConfiguration来配置缓存的写入器和缓存的配置。在RedisCacheConfiguration中,我们使用entryTtl方法设置了缓存过期时间为10分钟。 请注意,上述示例中的代码是Java代码,需要在Spring项目中使用。如果你使用其他语言或其他框架,可能需要根据具体情况进行相应的调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值