首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

步骤缓存

2013-07-11 
方法缓存介绍spring3.1之后提供了方法的缓存支持,透明的将缓存添加到应用中。这种缓存架构类似事务架构,提

方法缓存
介绍
  spring3.1之后提供了方法的缓存支持,透明的将缓存添加到应用中。这种缓存架构类似事务架构,提供了不同的缓存方案。

理解缓存架构
  缓存架构的核心在于缓存Java方法,减少方法执行次数。就是说当目标方法执行时,架构会检查指定参数的方便是否已经被执行过,如果没有则执行,并缓存结果返回;否则直接返回缓存结果并不执行方法。当然这种情况只针对方法执行结果结果不会变。

  缓存和缓冲区 
   缓冲区用于在读写操作之间开放的临时存储区,操作快的一方必须等待慢的一方因此影响性能。缓存区通过开放大的比较合适的数据块而不是单字节,以缓解这种性能损失,特征是单条记录读写只有一次,而且至少有一方知道这个缓存区

   缓存是隐藏的当缓存行为发生时都不知道缓存的存在,允许同一份数据被读多次来提高性能

利用缓存架构主要关注两个方面
  声明缓存-标志要缓存的方法及策略
  缓存配置-后端缓存 数据读和写的地方
我们只需要关注缓存逻辑行为而不是真正读写的地方。spring提供了两种开箱即用的缓存配置实现--JDK java.util.concurrent.ConcurrentMap和 EhCache,当然也支持其他插拔式的缓存提供者。

基于注解的声明式缓存
  架构提供了两种注解 @Cacheable 和 @CacheEvict,允许方法触发缓存存储和缓存剔除,接下来了解每种注解

@Cacheable
  用于声明需要缓存的方法。方法的结果被存储到缓存当下次相同参数的方法调用时返回缓存的结果,而不需要调用目标方法,注解指定了方法的缓存名字:



默认键值生成策略
缓存本质上由键值对实现,有必要为缓存的方法设计一个合理的键值以便访问缓存,架构提供了一个简单的KeyGenerator实现:
null值返回常数53没有参数,则返回0;只有一个参数,则返回参数本身多个参数,则计算所有参数的hash值并返回
一般情况下,只要hashcode()方法能反应键值就行。在分布式环境下如果参数实现remote接口,规定hashcode的实现中指定的是同一台服务器地址,而不同服务器上的相同方法hashcode必然不一样因此要作调整。不管在哪种环境,对这种算法来讲hashcode不可丢失。而且在同一jvm中,相同的hashcode能被不同的对象复用。

可以通过实现org.springframework.cache.KeyGenerator接口,提供不同的算法实现,配置如下

激活属性设置
proxy-target-class proxyTargetClass falseApplies to proxy mode only. Controls what type of caching proxies are created for classes annotated with the @Cacheable or @CacheEvict annotations. If the proxy-target-class attribute is set to true, then class-based proxies are created. If proxy-target-class is false or if the attribute is omitted, then standard JDK interface-based proxies are created. order order Ordered.LOWEST_PRECEDENCEDefines the order of the cache advice that is applied to beans annotated with @Cacheable or @CacheEvict. (For more information about the rules related to ordering of AOP advice, see the section called “Advice ordering”.) No specified ordering means that the AOP subsystem determines the order of the advice.

代理注意事项  
   当使用代理时@Cache*注解只适用于public方法,在proctected,package,private方法上使用时不会报错也不会有任何行为,可以使用AspectJ。
   当在接口上使用@Cache*时,对proxy-target-cache-manager="cacheManager"><cache:definitions cache="default"><cache:cacheable method="cache"/><cache:cacheable method="conditional" condition="#classField == 3"/><cache:cacheable method="key" key="#p0"/><cache:cacheable method="nam*" key="#root.methodName"/><cache:cacheable method="rootVars" key="#root.methodName + #root.method.name + #root.targetClass + #root.target"/><cache:cacheable method="nullValue" cache="default"/></cache:definitions><cache:definitions><cache:cache-evict method="invalidate" cache="default"/><cache:cache-evict method="evict" key="#p0" cache="default"/></cache:definitions><cache:caching cache="" condition="" key="" method=""><cache:cache-evict /><cache:cacheable /><cache:cache-put /></cache:caching></cache:advice>

我们使用过spring事务配置,缓存配置使用同样的方式


配置CacheManager
spring内置了JDK ConcurrentMap 和ehcache库两种实现
基于JDK ConcurrentMap实现

以上片段创建了两个缓存区default和books,就是@cache*中的名字。只适合于一般使用:测试、简单应用。不提供持久化和剔除策略。

基于ehcache实现


基于GemFire实现
GemFire 是面向内存的以磁盘为后端的有弹性、可扩展性的缓存,是spring团队开发的。

处理无后端存储的缓存
有时转换环境或做测试时,可能有些@Cache*没指定名字或指定的不存在。一般来说会报错,这种情况下,比起移除注解,更加优雅的方式就是指定一个假的缓存,什么也不做--就是说强制方法每次都执行


内嵌第三方缓存
有很多缓存产品被用来做后端存储器,为了使用它们我们必须自己实现cacheManager和cache因为每种产品没有同一的标准,spring提供了AbstractCacheManager模版可供实现。

热点排行