spring缓存代码详解

 更新时间:2018年02月02日 14:47:06   作者:txxs  
这篇文章主要介绍了spring缓存代码详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

本文研究的主要是spring缓存的相关内容,具体介绍如下。

这篇文章是根据谷歌翻译大致修改出来的,由于原文不知道是什么语,所以可能导致翻译的有错误和不准确的地方,但是大致的方向感觉还是蛮不错的,所以在这里整理了一下,希望能够有所帮助。

高速缓存一直是一个非常需要这两个提高应用程序性能并降低其工作量。此外,它的用处今天是特别明显,可以作出处理成千上万的游客concurrents.D'un架构上的Web应用,高速缓存管理正交于应用程序的业务逻辑和出于这个原因,应该对应用程序本身的发展产生的影响最小。从3.1版本开始,Spring提供了高速缓存管理的API,类似声明式事务管理。缓存的抽象接口,统一使用不同的缓存解决方案,对代码的影响最小。

spring用Java方法,对带有参数的组合第一次请求到一个方法,spring将返回值存储在高速缓存中。因此,下一个请求将是直接使用从高速缓存的值,而不必调用可能的高代价的方法。一切都透明地施加,而不会影响调用的方法。
在这篇文章中,我们将看到与Spring的两个不同的缓存存储的实现。

  • Java的ConcurrentHashMap
  • Ehcache

实现

spring和缓存的整合是简单透明的,通过@Cacheable注解标注需要缓存的方法

@Cacheable(value= "dataCache")  
public Reponse getDatas(Long param1, String param2){ } 

dataCache是相关联的高速缓存的名称。第一次调用这个方法的时候,该方法执行并将执行的结果存入以<参数1,参数2>哈希出来的秘钥为结果的结果集中去,当使用同样的参数再次调用的时候,这个方法不需要再次的执行。

有可能多于一个的缓存关联到我们的方法

@Cacheable({"dataCache",”default”})   
public Reponse getDatas(Long param1, String param2){  } 

在这种情况下,每个缓存都会在方法执行之前检查,如果有命中的话,则相关的值会被返回。

生成缓存键

一个缓存管理器的基本算法的占比比较小。缓存可以看做是一个存储器区域,在其中存储的对象个由唯一的秘钥进行映射。对象搜索的过程如下:

1、计算key(利用hash方法得到hashcode)
2、根据key值查找对象
3、如果找到对象返回该结果
4、如果找不到,则会计算实际与对象相关连的key,并把对象存入相应的位置

spring使用的是简单的哈希,它根据传递的方法参数生成key

自定义缓存

目标方法不能简单的根据参数产生不用的key,根据参数生成的仅仅是一些简单的情况

@Cacheable(value= "dataCache")   
public Reponse getDatas(Long param1, String param2, boolean param3){  } 

@Cacheable是允许开发人员自己指定key生成的方式的,可以使用spel表达式来做这件事情

@Cacheable(value= "dataCache", key="#param2")   
public Reponse getDatas(Long param1, String param2, boolean param3){   } 

上边的这种情况,缓存计算的秘钥的参数就仅仅是Parma2

spring也允许使用嵌套的属性

@Cacheable(value="dataCache", key=#param2.name")  
 public Reponse getDatas(Long param1, Data param2, boolean param3){} 

这种情况就是根据Parma2的name属性计算的秘钥

条件缓存

有一个缓存可能不适用于所用情况下的缓存,但是在某一些情况下需要缓存,缓存的时候根据SPEL表达式计算的真假来进行缓存的处理,如果条件为真的情况下则进行缓存

@Cacheable(value= "dataCache", key="#param2", condition="#param2.length<64")   
public Reponse getDatas(Long param1, String param2, boolean param3){  } 

在这种情况下是仅仅当第二个参数的长度小于64的时候才会进行缓存

@CacheEvict注解

spring的缓存不仅仅可以将数据进行缓存还可以清除缓存一个缓存存储。该过程用于去除过时的数据或不用的缓存数据。注解@ CacheEvict定义了执行缓存清空的方法,这些是删除缓存中数据的触发器。

@CacheEvict(value= "dataCache")   
public void reloadData(){  } 

这个选项是非常有必要的,当一个缓存的数据的需要清空的时候就会用到这个方法。

启用缓存

要启用一个spring项目对缓存的支持,我们需要再命名空间上增加对缓存注释的语句

<beans xmlns="http://www.springframework.org/schema/beans"     
    xmlns:cache="http://www.springframework.org/schema/cache"     
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xmlns:context="http://www.springframework.org/schema/context"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans       
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd       
    http://www.springframework.org/schema/cache       
    http://www.springframework.org/schema/cache/spring-cache.xsd       
    http://www.springframework.org/schema/context">   
  
<cache:annotation-driven /> 

删除注解可以禁用缓存,也可在我们的配置类中启用对缓存的使用

@Configuration   
@EnableCaching   
public class AppConfig {  } 

技术限制

对象传递方法的参数必须有自己的hashcode方法,以便用来计算秘钥

作为参数传递和返回的对象,它应该是可以序列化的

实现选择

spring提供了两种基本的实现:

  1. java的concurrentHashMap
  2. Ehcache

使用它们的时候,只需要声明适当的CacheManger和管理器的实体

使用java的ConcurrentHashMap

<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">   
<span style="white-space:pre">  </span><property name="caches">   
<span style="white-space:pre">    </span><set>   
<span style="white-space:pre">      </span><bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="default"/>   
<span style="white-space:pre">      </span><bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="dataCache"/>   
<span style="white-space:pre">    </span></set>   
<span style="white-space:pre">  </span></property>   
</bean> 

每个Manger都需要一个名称,通过注释来识别它。人们可以由一个Manger管理多个SimpleCacheManger,这个实现很基本不需要而外的库。

实现Ehcache

声明CacheManger

bean id="cacheManager"    
class="org.springframework.cache.ehcache.EhCacheCacheManager">   
 <property name="cacheManager" ref="ehcache"/>   
</bean>   
  
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
 <property name="configLocation" value="classpath:ehcache.xml"/>  
 <property name="shared" value="true"/>   
</bean> 

在ehcache.xml中文件是应用程序缓存参数文件:

<ehcache xsi:noNamespaceSchemaLocation="ehcache.xsd"    
  updateCheck="true"    
  monitoring="autodetect"    
  dynamicConfig="true"    
  maxBytesLocalHeap="150M">  
  
  <diskStore path="java.io.tmpdir"/>   
  <defaultCache eternal="false"  
   maxElementsInMemory="100"    
   overflowToDisk="false"/>  
  
  <cache name="dataCache"  
   eternal="false" 
   timeToIdleSeconds="300" 
   maxBytesLocalHeap="30M" 
   timeToLiveSeconds="300" 
   overflowToDisk="true" 
   diskPersistent="false" 
   diskExpiryThreadIntervalSeconds="120" 
   memoryStoreEvictionPolicy="LRU"/> 
  </ehcache> 

使用ehcache的,我们可以在一个非常简单的方式定义多个高速缓存不同的参数

名称:高速缓存的标识符

maxBytesLocalHeap:定义高速缓存可以使用虚拟机的字节数。如果一个的CacheManager maxBytesLocalHeap已经设置,则高速缓存的所确定的尺寸将被减去的CacheManager。其他缓存共享的休息。此属性的值是数据<编号> K | K | M | M | G | G代表千字节(K | K),兆字节(M | M)或千兆字节(G | G)。

永恒:定义元素是否是永恒的。如果是这样的情况下,超时将被忽略,该项目是永不过期。
timeToIdleSeconds:这是秒数,该项目自从他上次utilisation.La默认值为0住,元素保持静止
timeToLiveSeconds:这是秒数该项目已住自cache.La默认价值创造为0,该项目将永远活着。
memoryStoreEvictionPolicy掠夺政策:LRU - 最近最少使用,不经常使用的FIFO -先入先出,按创建日期最古老的元素。
diskExpiryThreadIntervalSeconds:的止赎过程控制两个运行之间的秒数。
diskPersistent:允许存储在磁盘上的虚拟机的两场比赛间的对象恢复对象。
overflowToDisk:确定对象是否可以被存储在磁盘上的情况下达到最大的存储元件的

总结用一个简单的数学公式:expirationTime = Math.min((creationTime + timeToLive),(mostRecentTime + timeToIdle))

总结

以上就是本文关于spring缓存代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • Java的特点和优点(动力节点整理)

    Java的特点和优点(动力节点整理)

    由于Java语言的设计者们十分熟悉C++语言,所以在设计时很好地借鉴了C++语言。可以说,Java语言是一种比C++语言“还面向对象”的一种编程语言,下面通过本文说下java的特点和优点
    2017-03-03
  • SpringBoot Filter修改返回内容,解决请求卡死200的错误

    SpringBoot Filter修改返回内容,解决请求卡死200的错误

    这篇文章主要介绍了SpringBoot Filter修改返回内容,解决请求卡死200的错误问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java HTTP协议收发MQ 消息代码实例详解

    Java HTTP协议收发MQ 消息代码实例详解

    这篇文章主要通过实例代码为大家详细介绍了如何在Java 环境下使用 HTTP 协议收发 MQ 消息,需要的朋友可以参考下
    2017-04-04
  • SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理

    SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理

    在spring cloud的项目中用到了feign组件,简单配置过后即可完成请求的调用。又因为有向请求添加Header头的需求,查阅了官方示例后,就觉得很简单,然后一顿操作之后调试报错...下面我们来详细了解
    2022-06-06
  • Java实现简单的飞机大战游戏(控制主飞机篇)

    Java实现简单的飞机大战游戏(控制主飞机篇)

    这篇文章主要为大家详细介绍了Java实现简单的飞机大战游戏,控制主飞机,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 我对@RestController注解的理解

    我对@RestController注解的理解

    这篇文章主要介绍了我对@RestController注解的理解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • JAVA | Guava EventBus 使用 发布/订阅模式的步骤

    JAVA | Guava EventBus 使用 发布/订阅模式的步骤

    这篇文章主要介绍了JAVA | Guava EventBus 使用 发布/订阅模式的步骤,帮助大家更好的理解和学习使用Guava EventBus,感兴趣的朋友可以了解下
    2021-03-03
  • java实现入栈push和出栈pop过程

    java实现入栈push和出栈pop过程

    文章详细介绍了栈的概念、特点以及如何使用数组和链表实现栈,通过入栈(push)和出栈(pop)操作,展示了栈的数据处理过程,并提供了具体的代码实现
    2024-12-12
  • JDK21无法导入TimeUnit类的解决办法

    JDK21无法导入TimeUnit类的解决办法

    这篇文章主要给大家介绍了关于JDK21无法导入TimeUnit类的解决办法,TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),需要的朋友可以参考下
    2024-01-01
  • java实战技巧之if-else代码优化技巧大全

    java实战技巧之if-else代码优化技巧大全

    代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,下面这篇文章主要给大家介绍了关于java实战技巧之if-else代码优化技巧的相关资料,需要的朋友可以参考下
    2022-02-02

最新评论