Springboot 使用注解操作多种缓存

@CacheConfig 作用在类上的配置型注解,cacheNames 设置key前缀, 默认会用::与后面的key拼接,cacheManger 指定缓存使用的cacheManger
@Cacheable 作用在方法上,先获取缓存,缓存没有就执行方法,将方法的返回值缓存起来,eg: @Cacheable(key = “#p0.id”, condition = “#p0.id!=null”) EL表达式参考源码注释
@CachePut 添加缓存:会替换掉现有的缓存 ;eg:@CachePut(key = “#result.id”, unless = “#result==null”)
@CacheEvict 缓存删除, 可以指定删除指定的key,也可以删除全部, 删除缓存的操作默认在方法执行后,通过beforeInvocation设置

配置Redis与caffeine的CacheManager


@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties({RedisProperties.class, CacheProperties.class})
public class CacheAutoConfig extends CachingConfigurerSupport {

    final Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;
    final JacksonProperties jacksonProperties;
    final RedisConnectionFactory redisConnectionFactory;

    @Bean
    public CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider<CacheManagerCustomizer<?>> customizers) {
        return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
    }


    /**
     * this CacheManager use redis cache data ;
     */
    @Bean
    @Primary
    public CacheManager remote(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers,
                               ObjectProvider<RedisCacheConfiguration> redisCacheConfiguration,
                               ObjectProvider<RedisCacheManagerBuilderCustomizer> redisCacheManagerBuilderCustomizers) {
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(
                determineConfiguration(cacheProperties, redisCacheConfiguration));
        List<String> cacheNames = cacheProperties.getCacheNames();
        if (!cacheNames.isEmpty()) {
            builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
        }
        redisCacheManagerBuilderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
        return cacheManagerCustomizers.customize(builder.build());
    }

    private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
            CacheProperties cacheProperties,
            ObjectProvider<RedisCacheConfiguration> redisCacheConfiguration) {
        return redisCacheConfiguration.getIfAvailable(() -> createConfiguration(cacheProperties));
    }

    private org.springframework.data.redis.cache.RedisCacheConfiguration createConfiguration(
            CacheProperties cacheProperties) {
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
                .defaultCacheConfig();
        config = config.serializeValuesWith(
                RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
                .computePrefixWith(name -> name + ":");

        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }

        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }


    /**
     * 使用Jackson序列化器
     */
    private RedisSerializer<Object> jackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
                Object.class);

        jackson2JsonRedisSerializer.setObjectMapper(buildMapper());
        return jackson2JsonRedisSerializer;
    }

    private ObjectMapper buildMapper() {

        ObjectMapper objectMapper = jackson2ObjectMapperBuilder.createXmlMapper(false).build();

        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        //设置类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);
        objectMapper.registerModule(new JavaTimeModule());

        //忽略null值
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return objectMapper;
    }

    /**
     * 配置缓存管理器
     *
     * @return 缓存管理器
     */
    @Bean
    public CacheManager local() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder().softValues()
                // 设置最后一次写入或访问后经过固定时间过期
                .expireAfterAccess(30, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(40000));
        return cacheManager;
    }

    @Bean
    public CacheLocalRedisResolver doubleCache(@Qualifier("local") CacheManager local, @Qualifier("remote") CacheManager remote) {
        return new CacheLocalRedisResolver(local, remote);
    }

}
/**
 * 本地缓存与redis缓存一起使用
 */
@RequiredArgsConstructor
public class CacheLocalRedisResolver implements CacheResolver {

    final CacheManager local;

    final CacheManager remote;


    @Override
    @NonNull
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {

        Collection<String> cacheNames = context.getOperation().getCacheNames();
        Collection<Cache> result = new ArrayList<>(cacheNames.size());
        for (String cacheName : cacheNames) {
            Cache localCache = local.getCache(cacheName);
            Cache remoteCache = remote.getCache(cacheName);

            result.add(localCache); // 顺序加入,优先使用本地缓存
            result.add(remoteCache);
            if (result.size() == 0) {
                throw new IllegalArgumentException("Cannot find cache named '" +
                        cacheName + "' for " + context.getOperation());
            }
        }

        return result;
    }

}

决定使用那种缓存时在注解中指定cacheManager =“beanName”

两种缓存组合使用: 指定cacheResolver=“doubleCache”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值