Spring缓存注解
2016-01-01 16:33
465 查看
概述
Spring 3.1引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如
EHCache 或者OSCache),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种
annotation,即能够达到缓存方法的返回对象的效果。
缓存的注解有以下三个
@Cancheable@CancheEvict @CachePut
引用缓存
package cacheOfAnno; importorg.springframework.cache.annotation.CacheEvict; importorg.springframework.cache.annotation.Cacheable; public class AccountService { @Cacheable(value="accountCache")// 使用了一个缓存名叫 accountCache public Account getAccountByName(StringuserName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 System.out.println("real queryaccount."+userName); return getFromDB(userName); } private Account getFromDB(String acctName) { System.out.println("real queryingdb..."+acctName); return new Account(acctName); } }
注意,此类的getAccountByName
方法上有一个注释 annotation,即 @Cacheable(value=”accountCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫
accountCache 的缓存中查询,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key
就是参数userName,value
就是Account
对象。“accountCache”缓存是在 spring*.xml
中定义的名称。
<beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven /> <bean id="accountServiceBean"class="cacheOfAnno.AccountService"/> <!-- generic cache manager --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" /> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="accountCache"/> </set> </property> </bean> </beans>
spring 配置文件有一个关键的支持缓存的配置项:<cache:annotation-driven />,这个配置项缺省使用了一个名字叫
cacheManager 的缓存管理器,这个缓存管理器有一个 spring
的缺省实现,即org.springframework.cache.support.SimpleCacheManager,这个缓存管理器实现了我们刚刚自定义的缓存管理器的逻辑,它需要配置一个属性
caches,即此缓存管理器管理的缓存集合,除了缺省的名字叫 default
的缓存,我们还自定义了一个名字叫accountCache
的缓存,使用了缺省的内存存储方案 ConcurrentMapCacheFactoryBean,它是基于
java.util.concurrent.ConcurrentHashMap 的一个内存缓存实现方案。
清空缓存
有了缓存的实现,我们还得清空缓存为了加入清空缓存的逻辑,我们只要对 AccountService.java 进行修改,从业务逻辑的角度上看,它有两个需要清空缓存的地方
当外部调用更新了账号,则我们需要更新此账号对应的缓存
当外部调用说明重新加载,则我们需要清空所有缓存
package cacheOfAnno; importorg.springframework.cache.annotation.CacheEvict; importorg.springframework.cache.annotation.Cacheable; public class AccountService { @Cacheable(value="accountCache")//使用了一个缓存名叫 accountCache public Account getAccountByName(StringuserName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 return getFromDB(userName); } @CacheEvict(value="accountCache",key="#account.getName()")//清空 accountCache 缓存 public void updateAccount(Account account) { updateDB(account); } @CacheEvict(value="accountCache",allEntries=true)// 清空 accountCache 缓存 public void reload() { } private Account getFromDB(String acctName) { System.out.println("real queryingdb..."+acctName); return new Account(acctName); } private void updateDB(Account account) { System.out.println("real updatedb..."+account.getName()); } }
按条件操作缓存
前面介绍的缓存方法,没有任何条件,即所有对 accountService 对象的 getAccountByName方法的调用都会起动缓存效果,不管参数是什么值,如果有一个需求,就是只有账号名称的长度小于等于 4 的情况下,才做缓存,大于 4 的不使用缓存,那怎么实现呢?Springcache 提供了一个很好的方法,那就是基于 SpEL 表达式的 condition 定义,这个condition 是 @Cacheable 注释的一个属性,下面我来演示一下
AccountService.java(getAccountByName方法修订,支持条件) @Cacheable(value="accountCache",condition="#userName.length()<= 4")// 缓存名叫 accountCache public Account getAccountByName(StringuserName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 return getFromDB(userName); }
其中的 condition=”#userName.length() <=4”,这里使用了 SpEL 表达式访问了参数 userName对象的 length() 方法,条件表达式返回一个布尔值,true/false,当条件为 true,则进行缓存操作,否则直接调用方法执行的返回结果
小结:
注解驱动能极大减少我们编写常见缓存代码量,通过少量标签和配置文件,可达到代码具备缓存的效果,灵活性很好。相关文章推荐
- Sun JDK监控和故障处理工具.
- JAVA线程间协作:Condition
- JAVA线程间协作:Condition
- win10怎么安装java?win10系统安装java的方法
- Java ConcurrentModificationException异常原因和解决方法
- Archive for required library:xxxxx/spring-beans-3.2.4.RELEASE.jar in project XXXXX cannot be read or is not a valid ZIP file
- java调用不同package的内部类
- 常见的Java不规范代码
- MyEclipse—怎样在MyEclipse中创建servlet3.0
- 设计模式——适配器模式 Java源代码
- 35个Java代码性能优化总结
- 基于Spring+AJAX的上传文件功能的实现
- java中的this关键字
- java socket 编程
- 回调--一个经典例子让你彻彻底底理解java回调机制
- java.util.Map的衍生
- Java部分总结图片版(已经加上原图链接下载!!!)
- java13.语言进阶------本地文件操作---文件夹的创建、重命名、删除
- MyEclipse 2015 stable2安装注册及配置说明
- MyEclipse设置注释格式