redis之@Cacheable注解

前言:为了将redis缓存部分的代码与业务代码分离开来,我们可以使用@Cacheable注解,该注解可以将方法返回的对象自动存入redis,在访问时又自动先从redis获取。

配置文件

除了基础的redis配置之后,我们还需添加一个config类将CacheManager类注入到容器中,key和value的序列化策略都可以在这里根据需要自由配置。

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.time.LocalDateTime;

@Configuration
public class RedisTemplateConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 配置序列化(解决乱码的问题)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 缓存有效期
//                .entryTtl(Duration.ofDays(1))
                // 使用StringRedisSerializer来序列化和反序列化redis的key值
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
                //.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer))
                //不添加缓存名称作为前缀
//                .disableKeyPrefix()
                // 禁用空值
                .disableCachingNullValues();

//        return RedisCacheManager.builder(connectionFactory)
//                .cacheDefaults(config)
//                .build();
        return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory), config) {
            @Override
            public RedisCache getCache(String name) {
                RedisCacheConfiguration cacheConfig = config.entryTtl(getDurationUntilNextDay());
                return super.createRedisCache(name, cacheConfig);
            }
            // 设置过期时间到第二天零点
            public Duration getDurationUntilNextDay() {
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime nextDay = now.toLocalDate().plusDays(1).atStartOfDay();
                return Duration.between(now, nextDay);
            }
        };
    }
}

业务使用

直接在service层实现类中的方法加上注解即可

@Override
    @Cacheable(cacheNames = "company:deploy", key ="#inVo.strYearMonth")
    public List<CompanyDeployVo> getDeployDetails(YearMonthInVo inVo) {
    	......
    }

如果对默认的key生成格式不满意,可添加一个KeyGenerator类来自定义生成key的格式,然后在@Cacheable注解上设置keyGenerator属性。

package com.terton.redis.config;
 
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;
 
import java.lang.reflect.Method;
import java.util.Arrays;
 
@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
//        String s = target.toString()+":"+method.getName()+":"+ Arrays.toString(params);
        String s = Arrays.toString(params);
        return s;
    }
}
@Cacheable(cacheNames = "company:deploy", keyGenerator = "customKeyGenerator"

此外,注解还支持指定条件生效,可自行查阅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值