文档章节

Spring Cache

lee123lee
 lee123lee
发布于 2016/09/20 17:59
字数 1969
阅读 69
收藏 5

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

Spring Cache 的支持有两种方法:

1、基于注解的配置;

2、基础XML配置。

 

通过注解使用 Cache

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

@Cacheable 可以注解在方法也可以注解在类上。当标记在方法上时,表示该方法是可以缓存的;如果标记在类上,则表示该类的所有方法都是可以缓存的。 对于一个支持缓存的方法,在执行后,会将其返回的结果进行缓存,以保证下次同样参数来执行该方法可以从缓存中返回结果,而不需要再次执行此方法。Spring Cache 方法的返回值是以键值对进行保存的,值就算返回结果。就 键 而言,Spring 支持两种策略,默认策略,自定义策略。

注意:一个支持缓存的方法,在对象内部被调用是不会触发缓存功能的。

 

@Cacheable 可以指定三个属性:value、key、condition

1、value 指定Cache的名称,必须指定,其表示该方法缓存的返回结果是被存放在哪个 Cache 上的,对应 Cache 的名称。其可以是一个Cache也可以是多个Cache(数组);

@Cacheable(value="Cx") //Cache是指定在Cx上面的,或者指定多个@Cahceable(value={"Cx","Cx1"})
public User getUser(Sting id){
  return ....;
}

2、key 自定义key,key属性是用来指定 Spring 缓存方法返回结果时所对应的 key 值的。该属性支持 EL 表达式。当我们没有指定key时,Spring会使用默认策略生成key。

自定义策略是表示我们通过EL表达式可以使用方法参数以及他们对应的属性。使用方法参数时,我们可以使用 "#参数名"。

@Cacheable(value="users",key = "#id")
public User find(Integer id){
  return null;
}
@Cacheable(value="users",key = "#user.id")
public User find(User user){
  return null;
}

除了上面使用方法参数作为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 直接 @Cacheable(key="caches[1].name")。因为他默认是使用的 #root

3、condition  指定发生条件   ,有时候坑呢个不需要缓存一个方法的所有结果,通过condition可以设置一个条件,其条件值是使用 SpringEL 表达式来指定的,当为TRUE时进行缓存处理;为FALSE时不进行缓存处理,即每次调用该方法都会执行。

@Cacheable(value={users},key="#user.id",condition="#user.id%2==0")
//只有这个用户的id为偶数的时候才会缓存

 

@CachePut  

@Cacheable 不同,它虽然也可以声明一个方法支持缓存,但它执行方法前是不会去检查缓存中是否存在之前执行过的结果,而每次都执行该方法,并将执行结果放入指定缓存中。

@CacheEvict

@CacheEvict标注在需要清楚缓存元素的方法和类上,@CacheEvict 可以指定的属性有 value、key、condition、allEntries 和 beforeInvocation。

  1. value 表示清除缓存作用在哪个Cache上;
  2. key是表示需要清除的是哪个key;
  3. allEntries是表示是否需要清除缓存中所有的元素。
  4. beforeInvocation 清除操作默认是在方法执行之后触发的。使用 beforeInvocation 可以改变除法清除操作的时间,当我们设置为TRUE时候,SPRING 会在调用该方法之前进行缓存的清除。

@Caching

@Caching 注解可以让我们在一个方法或者类上同时指定 Spring Cache 相关注解,其中拥有属性:cacheable、put、 evict。

@Caching(cacheable=@Cacheable("users"),evict={@CacheEvict("cache2"),@CacheEvict(value="cache3",allEntries=true)})

 

自定义注解的支持

@Target({ElementType.TYPE, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Cacheable(value="users")  
public @interface MyCacheable {  
   
}  

我们在需要缓存的方法上面使用 @MyCacheable可以达到同样的缓存效果。

 

 

配置SpringCache的支持

声明对Cache的支持

1.基于注解

配置Spring对注解Cache的支持,我们需要在Spring配置文件中添加Cache命名空间,然后通过

<cache:anotation-driven/>   

就可以启动Spring对注解Cache的支持。

其中

<cache:anotation-driven/>

有一个mode属性,可以选择值 proxy aspectj。默认使用proxy。当modeproxy时,只有缓存方法在外部被调用的时候才会生效。这也就意味着如果一个缓存方法在一个对象的内部被调用SpringCache是不会发生作用的。而modeaspectj时,就不会有这种问题了。另外使用proxy的时候,只有public方法上的@Cacheable才会发生作用。如果想非public上的方法也可以使用那么就把mode改成aspectj

注意:当我们 mode 使用 aspectj proxy-target-class true 时,定义在接口上的 Cache 注解是无法被识别的。

<cache:cache-driven/>

只会去寻找定义在同一个ApplicationContext下的 @Cacheable 等缓存注解。

 

2.基于XML配置

Spring还支持使用XML文件来配置,方式和配置事务管理类似。

<cache:advice id="cacheAdvice" cache-manager="cacheManager">  

      <cache:caching cache="users">  

         <cache:cacheable method="findById" key="#p0"/>  

         <cache:cacheable method="find" key="#user.id"/>  

         <cache:cache-evict method="deleteAll" all-entries="true"/>  

      </cache:caching>  

   </cache:advice>  

cache-manager 默认是 cacheManager。其中指定了将 findById find 方法缓存到 users 中。也可以使用通配符“*”

然后在配置 aop:config 指定定义好的 advice 作用到那些地方(pointcut

<aop:config proxy-target-class="false">  

      <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.xxx.UserService.*(..))"/>  

  </aop:config>  

 

3.配置CacheManager

CacheManager Spring 定义的一个用来管理 Cache 的接口。Spring自身提供了两种,一种是基于JAVA API的 ConcurrentMap,另一种是基于第三方Cache实现--Ehcache

基于ConcurrentMap的配置

<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  

      <property name="caches">  

         <set>  

            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="xxx"/>  

         </set>  

      </property>  

   </bean>  

p:name则是我们在注解时候使用的value(也就是使用的哪个cache)。

基于Ehcache的配置

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheManager"/>  

 <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;

 

自定义策略:

自定义策略是指我们通过SpringEL表达式来指定我们的key。这里的EL表达式可以使用参数以及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”

 

 

© 著作权归作者所有

lee123lee
粉丝 50
博文 144
码字总数 122159
作品 1
闵行
高级程序员
私信 提问

暂无文章

“旧城改造”的背后——银泰新零售阿里云解决方案(上)

相关免费课程《银泰新零售上云解决方案精讲》上线中 立足实战 讲透经典案例 助你快速理解新零售 第一节学习地址 第二节学习地址 传统线下商业体上云的案例 与其说银泰上云,倒不如说银泰“旧...

阿里云官方博客
6分钟前
0
0
记一次升级Oracle驱动引发的死锁

问题描述 近期项目需要从虚拟机环境迁移到容器环境,其中有一个项目在迁移到容器环境之后的两天之内出现了2次“死锁(deadlock)”的问题,部分关键日志如下: Found one Java-level deadlock:...

ksfzhaohui
8分钟前
2
0
MySQL 中的 information_schema 数据库

欢迎查看原文 - 本博客仅记录 https://blog.csdn.net/kikajack/article/details/80065753 -- 是否开启bin_log日志: off为关闭-- show variables like 'log_%'; show variables like '......

莫库什勒
16分钟前
0
0
Random在高并发下的缺陷以及JUC对其的优化

Random可以说是每个开发都知道,而且都用的很6的类,如果你说,你没有用过Random,也不知道Random是什么鬼,那么你也不会来到这个技术类型的社区,也看不到我的博客了。但并不是每个人都知道...

编程SHA
21分钟前
0
0
T5大牛带你解析:如何实现分布式技术

1.分布式事务 2. 分布式锁 Java 原生 API 虽然有并发锁,但并没有提供分布式锁的能力,所以针对分布式场景中的锁需要解决的方案。 分布式锁的解决方案大致有以下几种: 基于数据库实现 基于缓...

李红欧巴
33分钟前
32
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部