SpringCache使用

193 阅读2分钟

概述

本章主要讲解springcache的使用,不涉及到源码内容。后续会进行源码内容的分析。此篇为源码分析埋下伏笔。

简介

Spring Cache提供了 @Cacheable@CachePut@CacheEvict@Caching 等注解,通过注解的方式给在方法层面提供缓存的能力。

注解介绍

@EnableCaching

开启spring注解驱动缓存能力, 该注解主要是加载spring缓存能力所需要的一些配置,比如cacheManager(缓存器)、初始化inteceptor(方法拦截器)到BeanFactoryCacheOperationSourceAdvisor(缓存操作对象)中、AnnotationCacheOperationSource(缓存注解操作对象)

@Cacheable

用该注解注释方法代表被调用方法会走缓存(spring cache代理模式)。

参数介绍

public @interface Cacheable {

   /**
    * cacheNames的别名,跟cacheNames一个用户
    */
   @AliasFor("cacheNames")
   String[] value() default {};
   @AliasFor("value")
   
   /**
    * 缓存前缀,可用于区别命名空间
    */
   String[] cacheNames() default {};
   
   /**
    * 缓存的key
    */
   String key() default "";
   
   /**
    * 缓存key生成器
    */
   String keyGenerator() default "";
   
   /**
    * 缓存器对象-接口CacheManager对应的实现类,可选redis、map等缓存器
    */
   String cacheManager() default "";
   
   /**
    * 缓存解析器,用于从缓存上下文解析caches对象
    */
   String cacheResolver() default "";

   /**
    * 缓存命中条件,只有满足了el表达式的方法调用才会走缓存
    */
   String condition() default "";
   
   /**
    * 缓存排除条件,如果el表达式满足了,那么结果不走缓存,哪怕缓存中的确有对应值
    */
   String unless() default "";
   
   /**
    * 如果方法有相同key调用,那么走同步模式
    */
   boolean sync() default false;

}

@CacheEvict

参数介绍同Cacheable, 强制清除缓存,比如商品编辑场景,商品编辑以后,需要清除商品缓存。

@CachePut

方法查询不走缓存,但是更新缓存结果

@CacheConfig

可以使用在类上,主要修饰一些方法的公共参数,比如cacheManager、cacheNames、keyGenerator、cacheResolver,避免在方法上多次定义

注解使用案例

配置类

@Configuration
@EnableCaching
public class CacheConfig {
    /**
     * 分布式缓存(10秒)
     *
     * @param redisConnectionFactory *
     * @return *
     */
    @Bean("redisManager")
    public CacheManager distributionSecondLevel(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration configuration = RedisCacheConfiguration
                .defaultCacheConfig()
                .entryTtl(Duration.ofMillis(10 * 60 * 1000));
        return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(configuration).build();
    }

}

注解常用方式

package com.neko.seed.user.service;

import com.neko.seed.base.entity.Result;
import com.neko.seed.user.ao.CacheGetAO;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.PostMapping;

/**
 * @author lintiancheng
 */
public interface CacheService {
    /**
     * 根据参数中某些值做缓存
     * @param cacheGetAO
     * @return
     */
    @Cacheable(cacheNames = "CACHE_TEST_PREFIX", cacheManager = "redisManager", key = "#cacheGetAO.id + '_' + " +
            "#cacheGetAO.name")
    String get(CacheGetAO cacheGetAO);

    /**
     * 根据入参id做缓存
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "CACHE_TEST_PREFIX", cacheManager = "redisManager", key = "#id")
    String getById(Long id);

    /**
     * 指定某些id才做缓存,比如热点商品
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "CACHE_TEST_PREFIX", cacheManager = "redisManager", key = "#id", condition = "#id==7")
    String getHotById(Long id);

    /**
     * 不填写key,默认是对象中所有参数的组合
     * @param cacheGetAO
     * @return
     */
    @Cacheable(cacheNames = "CACHE_TEST_PREFIX", cacheManager = "redisManager")
    String search(CacheGetAO cacheGetAO);

    /**
     * 失效缓存,由于更新了信息。
     * @param id
     * @return
     */
    @CacheEvict(cacheNames = "CACHE_TEST_PREFIX", key = "#id")
    String updateId(Long id);
}