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

您可能感兴趣的文章:

  • 详解springboot整合ehcache实现缓存机制
  • spring-boot整合ehcache实现缓存机制的方法
  • Spring Boot 中使用cache缓存的方法
  • 浅谈SpringCache与redis集成实现缓存解决方案
  • 浅谈SpringBoot集成Redis实现缓存处理(Spring AOP实现)
  • SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法
  • springboot+mybatis+redis 二级缓存问题实例详解
  • SpringBoot项目中使用redis缓存的方法步骤
时间: 2018-02-01

Spring Boot 中使用cache缓存的方法

一.什么是缓存 Cache Cache 一词最早来自于CPU设计 当CPU要读取一个数据时,首先从CPU缓存中查找,找到就立即读取并送给CPU处理:没有找到,就从速率相对较慢的内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存.正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在CPU缓存中,只有大约10%需要从内存读取.这大大节省了CPU直接读取内存的

SpringBoot项目中使用redis缓存的方法步骤

本文介绍了SpringBoot项目中使用redis缓存的方法步骤,分享给大家,具体如下: Spring Data Redis为我们封装了Redis客户端的各种操作,简化使用. - 当Redis当做数据库或者消息队列来操作时,我们一般使用RedisTemplate来操作 - 当Redis作为缓存使用时,我们可以将它作为Spring Cache的实现,直接通过注解使用 1.概述 在应用中有效的利用redis缓存可以很好的提升系统性能,特别是对于查询操作,可以有效的减少数据库压力. 具体的代码参照该

浅谈SpringCache与redis集成实现缓存解决方案

缓存可以说是加速服务响应速度的一种非常有效并且简单的方式.在缓存领域,有很多知名的框架,如EhCache .Guava.HazelCast等.Redis作为key-value型数据库,由于他的这一特性,Redis也成为一种流行的数据缓存工具. 在传统方式下对于缓存的处理代码是非常臃肿的. 例如:我们要把一个查询函数加入缓存功能,大致需要三步. 一.在函数执行前,我们需要先检查缓存中是否存在数据,如果存在则返回缓存数据 二.如果不存在,就需要在数据库的数据查询出来. 三.最后把数据存放在缓存中,当

spring-boot整合ehcache实现缓存机制的方法

EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. ehcache提供了多种缓存策略,主要分为内存和磁盘两级,所以无需担心容量问题. spring-boot是一个快速的集成框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 由于spring-boot无需任何样板化的配置文件,所以spring-boot集成一些其他框架时会有略微的

详解springboot整合ehcache实现缓存机制

EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. ehcache提供了多种缓存策略,主要分为内存和磁盘两级,所以无需担心容量问题. spring-boot是一个快速的集成框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 由于spring-boot无需任何样板化的配置文件,所以spring-boot集成一些其他框架时会有略微的

SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法

介绍 使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验. 使用redis做mybatis的二级缓存可是内存可控<如将单独的服务器部署出来用于二级缓存>,管理方便. 1.在pom.xml文件中引入redis依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifac

浅谈SpringBoot集成Redis实现缓存处理(Spring AOP实现)

第一章 需求分析 计划在Team的开源项目里加入Redis实现缓存处理,因为业务功能已经实现了一部分,通过写Redis工具类,然后引用,改动量较大,而且不可以实现解耦合,所以想到了Spring框架的AOP(面向切面编程). 开源项目:https://github.com/u014427391/jeeplatform 第二章 SpringBoot简介 Spring框架作为JavaEE框架领域的一款重要的开源框架,在企业应用开发中有着很重要的作用,同时Spring框架及其子框架很多,所以知识量很广.

springboot+mybatis+redis 二级缓存问题实例详解

前言 什么是mybatis二级缓存? 二级缓存是多个sqlsession共享的,其作用域是mapper的同一个namespace. 即,在不同的sqlsession中,相同的namespace下,相同的sql语句,并且sql模板中参数也相同的,会命中缓存. 第一次执行完毕会将数据库中查询的数据写到缓存,第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率. Mybatis默认没有开启二级缓存,需要在全局配置(mybatis-config.xml)中开启二级缓存. 本文讲述的是使用Redi

MyBatis 动态SQL和缓存机制实例详解

有的时候需要根据要查询的参数动态的拼接SQL语句 常用标签: - if:字符判断 - choose[when...otherwise]:分支选择 - trim[where,set]:字符串截取,其中where标签封装查询条件,set标签封装修改条件 - foreach: if案例 1)在EmployeeMapper接口文件添加一个方法 public Student getStudent(Student student); 2)如果要写下列的SQL语句,只要是不为空,就作为查询条件,如下所示,这样

SpringBoot学习系列之MyBatis Plus整合封装的实例详解

前言 MyBatis-Plus是一款MyBatis的增强工具(简称MP),为简化开发.提高效率,但我们并没有直接使用MP的CRUD接口,而是在原来的基础上封装一层通用代码,单表继承我们的通用代码,实现了单表的基础get.save(插入/更新).list.page.delete接口,使用Vo去接收.传输数据,实体负责与数据库表映射. 这样做的目的是与我们之前的那套jpa保持编码风格上的一致,当我们的通用接口不能满足要求时,应当先考虑使用MP的Service层CRUD接口,然后是Mapper的接口,

Java实现LRU缓存的实例详解

Java实现LRU缓存的实例详解 1.Cache Cache对于代码系统的加速与优化具有极大的作用,对于码农来说是一个很熟悉的概念.可以说,你在内存中new 了一个一段空间(比方说数组,list)存放一些冗余的结果数据,并利用这些数据完成了以空间换时间的优化目的,你就已经使用了cache. 有服务级的缓存框架,如memcache,Redis等.其实,很多时候,我们在自己同一个服务内,或者单个进程内也需要缓存,例如,lucene就对搜索做了缓存,而无须依赖外界.那么,我们如何实现我们自己的缓存?还

MyBatis Properties及别名定义实例详解

上一篇我们介绍了mybatis的增删改查入门实例,我们发现在 mybatis-configuration.xml 的配置文件中,对数据库的配置都是硬编码在这个xml文件中,如下图,那么我们如何改进这个写法呢? 1.我们将 数据库的配置语句写在 db.properties 文件中 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm jdbc.username=root jdbc.password=ro

Redis Set 集合的实例详解

 Redis Set 集合的实例详解 Redis的Set是string类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复的数据. redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1). 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员). 实例 redis 127.0.0.1:6379> SADD runoobkey redis (integer) 1 redis 127.0.0.1:6379> SADD ru

C语言中二级指针的实例详解

C语言中二级指针的实例详解 用图说明 示例代码: #include <stdio.h> int main(int argc, const char * argv[]) { // int a = 5; int *p1 = &a; //-打印地址-----地址相同--------------- printf("&a = %p\n", &a);// printf("p1 = %p\n", p1);// int **p2 = &p

微信小程序之数据缓存的实例详解

微信小程序之数据缓存的实例详解 前言: 在H5之前,缓存一般都是用cookie,但是cookie的存储空间太小.于是,H5增加了新的缓存机制,即localstorage 和 sessionstorage,具体的介绍就不在多说.在微信小程序中,数据缓存其实就和localstorage 的原理差不多,所以理解起来并不难.下面我们来一起实现一下. 效果图展示: 我们在index页面存入数字11,然后在跳转到新页面,在将缓存中的11取出渲染到当前页面.具体代码如下: index页面: <span sty

MyBatis动态SQL标签用法实例详解

1.动态SQL片段 通过SQL片段达到代码复用 <!-- 动态条件分页查询 --> <sql id="sql_count"> select count(*) </sql> <sql id="sql_select"> select * </sql> <sql id="sql_where"> from icp <dynamic prepend="where&quo

SpringBoot 集成Kaptcha实现验证码功能实例详解

在一个web应用中验证码是一个常见的元素.不管是防止机器人还是爬虫都有一定的作用,我们是自己编写生产验证码的工具类,也可以使用一些比较方便的验证码工具.在网上收集一些资料之后,今天给大家介绍一下kaptcha的和springboot一起使用的简单例子. 准备工作: 1.你要有一个springboot的hello world的工程,并能正常运行. 2.导入kaptcha的maven: <!-- https://mvnrepository.com/artifact/com.github.penggl