• Spring Cache使用详解


    Spring Cache

    Spring Cache使用方法与Spring对事务管理的配置相似。Spring Cache的核心就是对某个方法进行缓存,其实质就是缓存该方法的返回结果,并把方法参数和结果用键值对的方式存放到缓存中,当再次调用该方法使用相应的参数时,就会直接从缓存里面取出指定的结果进行返回。所以在使用Cache的时候我们要保证我们缓存的方法对于相同的参数要有相同的返回结果。
    -----------Spring对Cache的支持有两种方法:
    1.基于注解的配置
    2.基础XML配置

    -----------------------------------------------------通过注解去使用到Cache------------------------------------------
    @Cacheable-------使用这个注解的方法在执行后会缓存其返回结果。
    @CacheEvict--------使用这个注解的方法在其执行前或执行后移除Spring Cache中的某些元素。

    ---------------------------------------@Cacheable----------------------------
    @Cacheable可以注解在方法上也可以注解在类上。当标记在方法上面时,表示该方法是可以缓存的;如果标记在类上面,则表示该类的所有方法都是可以缓存的。对于一个支持缓存的方法,在执行后,会将其返回结果进行缓存起来,以保证下次同样参数来执行该方法的时候可以从缓存中返回结果,而不需要再次执行此方法。Spring缓存方法的返回值是以键值对进行保存的,值就是返回结果,键的话Spring支持两种策略,一种是默认策略,一种是自定义策略。
    注意:一个支持缓存的方法,在对象内部被调用是不会触发缓存功能的。
    @Cacheable可以指定三个属性:value、key、condition。

    ----------------------value:指定Cache的名称
    value值是必须指定的,其表示该方法缓存的返回结果是被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以使多个Cache(数组);
    eg:
    [java] view plain copy
     print?
    1. @Cache(value="Cx")//Cache是指定在Cx上面的  或者指定多个@Cache(value={"Cx","Cx1"})  
    2. public User getUser(String id){  
    3.     return .....;  
    4. }  
    -----------------------key:自定义key
    key属性是用来指定Spring缓存方法返回结果时所对应的key值的。该属性支持EL表达式。当我们没有指定key时,Spring会使用默认策略生成key。·
    -----------key的自定义策略:
    自定义策略是表示我们通过EL表达式来指定我们的key。这里EL表达式可以使用方法参数以及他们对应的属性。使用方法参数时,我们可以使用“#参数名”。
    eg:
    [java] view plain copy
     print?
    1. @Cacheable(value="users", key="#id")  
    2. public User find(Integer id) {  
    3.      returnnull;  
    4. }  

    [java] view plain copy
     print?
    1. @Cacheable(value="users", key="#user.id")  
    2. public User find(User user) {  
    3.     returnnull;  
    4. }  
    除了上面使用方法参数作为Key以外,Spring还为我们提供了一个root对象可以生成key。通过root对象我们还可以获取到
    -------1.methodName  当前方法名    #root.methodName
    -------2.method       当前方法  #root.method.name
    -------3.target   当前被动用对象 #root.target
    -------4.targetClass      当前被调用对象Class#root.targetClass
    -------5.args    当前方法参数组成的数组 #root.args[0]
    -------6.caches    当前被调用方法所使用的Cache #root.caches[0],name
    当我们要使用root作为key时,可以不用写root直接@Cache(key="caches[1].name")。因为他默认是使用#root的

    -----------------condition:指定发生条件
    有时候可能不需要缓存一个方法的所有结果。通过condition可以设置一个条件,其条件值是使用SpringEL表达式来指定的。当为true时进行缓存处理;为false时不进行缓存处理,即每次调用该方法都会执行。
    eg:
    [java] view plain copy
     print?
    1. @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")  
    这个则是当用户id为偶数的时候才会缓存。

    -----------------------------------------------------@CachePut------------------------------------------
    与@Cacheable不同,它虽然也可以声明一个方法支持缓存,但它执行方法前是不会去检查缓存中是否存在之前执行过的结果,而是每次都执行该方法,并将执行结果放入指定缓存中。
    -----------------------------------------------------@CacheEvict----------------------------------------
    @CacheEvict标注在需要清楚缓存元素的方法和类上。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。value表示清除缓存作用在哪个Cache上;key是表示需要清除的是哪个key。
    --------------allEntries是表示是否需要清除缓存中所有的元素。
    --------------beforeInvocation
    清除操作默认是在方法成功执行之后触发的。使用beforeInvocation可以改变触发清除操作的时间,当我们设置为true时,Spring会在调用该方法之前进行缓存的清除。
    ------------------------------------------------------@Caching-------------------------------------------
    @Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关注解,其中拥有属性:cacheable、put、evict。
    [java] view plain copy
     print?
    1. @Caching(cacheable=@Cacheable("users"),evict={@CacheEvict("cache2"),@CacheEvict(value="cache3",allEntries=true)})<span style="font-family: Arial, Helvetica, sans-serif;">    </span>  

    -------------------------------------------------------自定义注解-----------------------------------------
    [java] view plain copy
     print?
    1. @Target({ElementType.TYPE, ElementType.METHOD})  
    2. @Retention(RetentionPolicy.RUNTIME)  
    3. @Cacheable(value="users")  
    4. public @interface MyCacheable {  
    5.    
    6. }  
    我们在需要缓存的方法上面使用@MyCacheable可以达到同样的缓存效果。


    ----------------------------------------------------------------------------------------------------------------------------------------------
    --------------------------配置Spring对Cache的支持
    声明对Cache的支持
    1.基于注解
    配置Spring对注解Cache的支持,我们需要在Spring配置文件中添加Cache命名空间,然后通过<cache:anotation-driven/>
    就可以启动Spring对注解Cache的支持。
    其中<cache:anotation-driven/>有一个mode属性,可以选择值proxy和aspectj。默认使用proxy。当mode为proxy时,只有缓存方法在外部被调用的时候才会生效。这也就意味着如果一个缓存方法在一个对象的内部被调用SpringCache是不会发生作用的。而mode为aspectj时,就不会有这种问题了。另外使用proxy的时候,只有public方法上的@Cacheable才会发生作用。如果想非public上的方法也可以使用那么就把mode改成aspectj。
    注意:当我们mode使用aspectj和proxy-target-class为true时,定义在接口上的Cache注解是无法被识别的。<cache:cache-driven/>只会去寻找定义在同一个ApplicationContext下的@Cacheable等缓存注解。

    2.基于XML配置
    Spring还支持使用XML文件来配置,方式和配置事务管理类似。
    [java] view plain copy
     print?
    1. <cache:advice id="cacheAdvice" cache-manager="cacheManager">  
    2.       <cache:caching cache="users">  
    3.          <cache:cacheable method="findById" key="#p0"/>  
    4.          <cache:cacheable method="find" key="#user.id"/>  
    5.          <cache:cache-evict method="deleteAll" all-entries="true"/>  
    6.       </cache:caching>  
    7.    </cache:advice>  
    cache-manager默认是cacheManager。其中指定了将findById和find方法缓存到users中。也可以使用通配符“*”
    然后在配置aop:config指定定义好的advice作用到那些地方(pointcut)
    [java] view plain copy
     print?
    1. <aop:config proxy-target-class="false">  
    2.       <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.xxx.UserService.*(..))"/>  
    3.    </aop:config>  

    3.配置CacheManager
    CacheManager是Spring定义的一个用来管理Cache的接口。Spring自身提供了两种,一种是基于JAVA API的ConcurrentMap,另一种是基于第三方Cache实现--Ehcache。
    ---------------------基于ConcurrentMap的配置
    [java] view plain copy
     print?
    1. <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
    2.       <property name="caches">  
    3.          <set>  
    4.             <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="xxx"/>  
    5.          </set>  
    6.       </property>  
    7.    </bean>  
    p:name则是我们在注解时候使用的value(也就是使用的哪个cache)。
    ---------------------基于Ehcache的配置
    [java] view plain copy
     print?
    1. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheManager"/>  
    2.    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache-spring.xml"/>  
    它是通过指定的ehcache配置文件来生成的一个Ehcache的CacheManager。若未指定则默认规则取classpath路径下的ehcache文件,若还是不存在则取Ehcache对应包的ehcache-failsafe.xml文件作为配置文件。


    ---------------------------------------------------------键的生成策略-----------------------------------------------------------
    键的生成策略有两种,一种是默认策略,一种是自定义策略。
    ----------------------------默认策略:
    默认的key是通过KeyGenerator生成的,其默认策略如下:
    1.如果方法没有参数,则使用0作为key;
    2.如果只有一个参数的话则使用该参数作为key;
    3.如果参数多于一个则使用所有参数的hashcode作为key;

    ----------------------------自定义策略:
    自定义策略是指我们通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用参数以及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。
  • 相关阅读:
    oldboy_09_03day_test1
    oldboy_09_03day
    java消息队列
    es6语法([...arr], set/map数据结构,数组扩展,箭头函数等)
    Angular 2 Expression Changed After It Has Been Checked Exception
    jQuery之Deferred对象详解
    js面向对象:Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
    Angular 4.x 动态创建组件
    JS中this的四种用法
    typescript主键自增长
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696309.html
Copyright © 2020-2023  润新知