`

spring Ehcache @Cacheable 详解

阅读更多

原文地址  http://jinnianshilongnian.iteye.com/blog/2001040

@CachePut 

应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存: 

Java代码   收藏代码
  1. @CachePut(value = "user", key = "#user.id")  
  2. public User save(User user) {  
  3.     users.add(user);  
  4.     return user;  
  5. }  

即调用该方法时,会把user.id作为key,返回值作为value放入缓存;

 

@CachePut注解:

Java代码   收藏代码
  1. public @interface CachePut {  
  2.     String[] value();              //缓存的名字,可以把数据写到多个缓存  
  3.     String key() default "";       //缓存key,如果不指定将使用默认的KeyGenerator生成,后边介绍  
  4.     String condition() default ""//满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断  
  5.     String unless() default "";    //用于否决缓存更新的,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了  
  6. }  

 

@CacheEvict 

即应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据:

Java代码   收藏代码
  1. @CacheEvict(value = "user", key = "#user.id"//移除指定key的数据  
  2. public User delete(User user) {  
  3.     users.remove(user);  
  4.     return user;  
  5. }  
  6. @CacheEvict(value = "user", allEntries = true//移除所有数据  
  7. public void deleteAll() {  
  8.     users.clear();  
  9. }  

 

@CacheEvict注解:

Java代码   收藏代码
  1. public @interface CacheEvict {  
  2.     String[] value();                        //请参考@CachePut  
  3.     String key() default "";                 //请参考@CachePut  
  4.     String condition() default "";           //请参考@CachePut  
  5.     boolean allEntries() default false;      //是否移除所有数据  
  6.     boolean beforeInvocation() default false;//是调用方法之前移除/还是调用之后移除  

 

@Cacheable

应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中:

Java代码   收藏代码
  1. @Cacheable(value = "user", key = "#id")  
  2.  public User findById(final Long id) {  
  3.      System.out.println("cache miss, invoke find by id, id:" + id);  
  4.      for (User user : users) {  
  5.          if (user.getId().equals(id)) {  
  6.              return user;  
  7.          }  
  8.      }  
  9.      return null;  
  10.  }  

 

@Cacheable注解:

Java代码   收藏代码
  1. public @interface Cacheable {  
  2.     String[] value();             //请参考@CachePut  
  3.     String key() default "";      //请参考@CachePut  
  4.     String condition() default "";//请参考@CachePut  
  5.     String unless() default "";   //请参考@CachePut    

 

运行流程

Java代码   收藏代码
  1. 1、首先执行@CacheEvict(如果beforeInvocation=true且condition 通过),如果allEntries=true,则清空所有  
  2. 2、接着收集@Cacheable(如果condition 通过,且key对应的数据不在缓存),放入cachePutRequests(也就是说如果cachePutRequests为空,则数据在缓存中)  
  3. 3、如果cachePutRequests为空且没有@CachePut操作,那么将查找@Cacheable的缓存,否则result=缓存数据(也就是说只要当没有cache put请求时才会查找缓存)  
  4. 4、如果没有找到缓存,那么调用实际的API,把结果放入result  
  5. 5、如果有@CachePut操作(如果condition 通过),那么放入cachePutRequests  
  6. 6、执行cachePutRequests,将数据写入缓存(unless为空或者unless解析结果为false);  
  7. 7、执行@CacheEvict(如果beforeInvocation=false 且 condition 通过),如果allEntries=true,则清空所有  

流程中需要注意的就是2/3/4步:

如果有@CachePut操作,即使有@Cacheable也不会从缓存中读取;问题很明显,如果要混合多个注解使用,不能组合使用@CachePut和@Cacheable;官方说应该避免这样使用(解释是如果带条件的注解相互排除的场景);不过个人感觉还是不要考虑这个好,让用户来决定如何使用,否则一会介绍的场景不能满足。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics