好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Spring 缓存抽象示例详解

spring 缓存 抽象 概述

spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.cache和org.springframework.cache.cachemanager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成。

cache接口为缓存的组件规范定义,包含缓存的各种操作集合;

cache接口下spring提供了各种xxxcache的实现:如rediscache,ehcachecache , concurrentmapcache等;

cachemanager接口为缓存管理器规范,简单来说就是用于存放cache,spring默认也提供了一些列管理器的实现。

spring缓存抽象提供了5个注解用来声明缓存规则:

@cacheable:能够根据方法的请求参数对其结果进行缓存,多用于查询

@cacheput: 执行方法,并缓存结果

@cacheevict:清空缓存

@caching:能够同时应用多个缓存注解功能

@cacheconfig: 用于抽取缓存的公共配置(类级别)

以上5个注解除了@cacheconfig注解是类级别的注解,其余4个注解在类和方法上均可以使用,作用在类上表示对该类下所有方法生效,作用的方法上只对该方法生效,且只能用于public修饰的符方法,protected或者private修饰的方法不适用。

@cacheable注解

@cacheable注解的作用是spring在调用该方法之前,首先在缓存中查找方法的返回值,默认的key是根据参数值生成,如果存在,直接返回缓存中的值,否则执行该方法,并将返回值保存到缓存中

@cacheable运行流程:

  1.方法运行之前,先去查询cache(缓存组件),按照cachenames指定的名字获取;

           (cachemanager先获取相应的缓存),第一次获取缓存如果没有cache组件会自动创建。

  2.去cache中查找缓存的内容,使用一个key,默认就是方法的参数值;

           key是按照某种策略生成的;默认是使用keygenerator生成的,              

     spring默认加载的是simplecachemanage,simplekeygenerator生成key的默认策略是:

                       如果没有参数;key=new simplekey()

                       如果有一个参数:key=参数的值

                       如果有多个参数: key=new simplekey(params)

  3.没有查到缓存就调用目标方法;

  4.将目标方法返回的结果,放进缓存中

@cacheable属性说明:

  1.achenames/value:该属性值必须提供,指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;

      如:cachenames = "product"或者cachenames = {"product1","product2"}

  2.key:缓存数据使用的key,不指定key则默认是使用方法参数的值该属性值支持spel表达式

       3.cachemanager:指定缓存管理器;或者cacheresolver指定获取解析器

       4.condition:指定符合条件的情况下才缓存

  5.unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断

                  unless = "#result == null"

                   unless = "#a0==2":如果第一个参数的值是2,结果不缓存;

  6.sync:是否使用异步模式

使用示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@cacheable (cachenames = "product" ) // 默认key为参数,多个参数simplekey [arg1,arg2]

//@cacheable(cachenames = "product",key = "#root.methodname+'['+#id+']'")

//@cacheable(cachenames = "product",keygenerator = "mykeygenerator")

//@cacheable(cachenames = "product",key = "#root.methodname+'['+#id+']'",condition="#a0>10",unless = "#a0==11") //带条件的缓存满足condition=true缓存,满足unless=true则不缓存

public product getproductbyid( long id){

   product product =productmapper.getproductbyid(id);

   system.out.println(product);

   return product;

}

//指定key属性值

@cacheable (cachenames = "product" , key= "#id" )  //]#+参数名]的形式,直接使用参数名

//或者

//@cacheable(cachenames ="product", key="#a0")  //]#a+参数位置]的形式

   public product getproductbyid( long id) {

    xxxx

   }

@cacheable (cachenames = "product" , key= "# productcondition.productid" ) 

//或者

//@cacheable(cachenames ="product", key="#a0.productid") 

   public product getproduct (product productcondition) {

    xxxx

   }

自定义key生成器

除了通过spel表达式之外,还可以通过自定义key生成器的方式,spring缓存模块提供了 org.springframework.cache.interceptor.keygenerator 接口用于缓存key的生成声明,因此我们可以自定义一个mykeygenerator类并实现了keygenerator接口 ,使用如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

@configuration

public class mycacheconfig {

   @bean ( "mykeygenerator" )

   public keygenerator keygenerator(){

     return new keygenerator(){

       @override

       public object generate(object target, method method, object... params) {

         return method.getname()+ "[" + arrays.aslist(params).tostring()+ "]" ;

       }

     };

   }

}

该方法测试用,关于缓存key的生成方式,网上有很多种策略。

使用时只需要修改注解的key属性即可:

?

1

@cacheable (cachenames = "product" ,keygenerator = "mykeygenerator" )

 @cacheput

@cacheput注解的作用简单的说一句话:既调用方法,又缓存数据。@cacheput和@cacheable两个注解都可以用于填充缓存,但使用上略有点差异,@cacheable注解的执行流程是先在按key在缓存中查找,存在则返回,不存在则执行目标方法,并缓存目标方法的结果。而@cacheput并不会检查缓存,总是先执行目标方法,并将目标方法的结果保存到缓存中。实际中比如执行到更新操作时,则希望将最新的数据更新到缓存,如果该方法返回异常,将不再执行保存缓存的逻辑。

@cacheput属性说明

@cacheput注解属性与@cacheput类似,并没有增加其他属性

使用示例:

?

1

2

3

4

5

6

7

8

9

10

@cacheput (value= "product" ,key = "#result.productid" ,condition = "#result!=null" )

public product updateproduct(product product){

   int count = productmapper.updateproduct(product);

   system.out.println( "影响行数:" +count);

   if (count> 0 ){

     return product;

   } else {

     return null ;

   }

}

@cacheevict注解

该注解的作用根据指定的key或者是allentries属性值移除缓存中特性的键值对。

@cacheevict属性说明

与@cacheable相比@cacheevict注解提供了另外两个属性:

1.allentries:表示是否清空所有缓存内容,默认false,如果该值为true则清空指定cachenames缓存块下所有内容,如果指定了allentries为true,那么再zhidingkey值将没有意义

2.beforeinvocation:是否在执行方法前请空缓存,默认值为false,如果该值为true则在调用目标方法前执行清空缓存,为false的情况下,如果目标方法抛出异常,则不再执行清空缓存逻辑

示例:

?

1

2

3

4

5

6

7

//@cacheevict(value="product",key="#id")

//@cacheevict(value="product",allentries = true) //清楚所有缓存

@cacheevict (value= "product" ,allentries = true ,beforeinvocation = true ) //清楚所有缓存

public boolean deleteproductbyid( long id) {

   productmapper.deleteproductbyid(id);

   return true ;

}

@caching注解

该注解是一个分组注解,作用是可以同时应用多个其他注解,该注解提供了3个属性cacheable,put,evict分别用于组合@cacheable、@cacheput、@cacheevict三个注解

使用示例:

?

1

2

3

4

5

6

7

8

9

10

11

@caching (

      cacheable = { @cacheable (value= "product" ,key= "#productname" )},

      put = {

          @cacheput (value= "product" ,key= "#result.productid" ),

          @cacheput (value= "product" ,key= "#result.productname" )

      }

  )

  public product getproductbyname(string productname){

    product product =productmapper.getproductbyname(productname);

    return product;

  }

当@cacheing同时含有cacheput注解和cacheable注解时,仍然会先执行目标方法。(并不是按@cacheable的执行过程,先检查缓存,存在则返回)

@cacheconfig

是一个类级别的注解,允许共享缓存的名称、keygenerator、cachemanager 和cacheresolver

示例:

?

1

2

3

4

@service

  @cacheconfig (cachenames = "product" )

  public class productservice {

  }

在类上使用该注解,指定cachenames属性值,则类中方法上的注解将默认继承了该属性值,如果方法上注解使用和了@cacheconfig向同的属性,则以方法上的为准。

?

1

2

3

4

5

6

7

8

9

10

11

12

@service

@cacheconfig (cachenames = "product" )

public class productservice {

   @autowired

   private productmapper productmapper;

   @cacheable (cachenames = "product1" ,key = "#root.methodname+'['+#id+']'" )

   public product getproductbyid( long id){

     product product =productmapper.getproductbyid(id);

    system.out.println(product);

    return product;

   }

}

上面@cacheable和@cacheconfig都指定了属性值cacaenames,实际以方法上注解指定的为准。

spring缓存抽象的关键原理就是使用spring aop,通过切面实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。

总结

以上所述是小编给大家介绍的spring 缓存抽象示例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

原文链接:https://www.cnblogs.com/ashleyboy/p/9591604.html

查看更多关于Spring 缓存抽象示例详解的详细内容...

  阅读:44次