Spring 3.1中开始对缓存提供支持,核心思路是对方法的缓存,当我们调用一个方法时,将方法的参数和返回值作为 key/value缓存起来,当再次调用该方法时,如果缓存中有数据,就直接从缓存中获取,否则再去执行该方法。

Spring并未提供缓存的实现,我们可以自由选择缓存的实现,目前Spring Boot支持的缓存有 JCache、EhCache 2.x、Redis....。不过无论使用那种缓存实现,不同的只是缓存配置,开发者使用的缓存注解都是一样的。

一、使用 Ehchche 2.x 缓存

1,添加依赖

首先编辑项目的pom.xml文件,添加 spring-boot-starter-cache 依赖以及 Ehcache依赖:

org.springframework.boot

spring-boot-starter-cache

net.sf.ehcache

ehcache

2,添加缓存配置文件

在 resources目录下创建ehcache.xml 文件作为 Ehcache缓存的配置文件,内容如下:

(1)如果 Ehcache的依赖存在,并且在 classpath下又一个名为encache.xml 的 Ehcache配置文件,那么 EhCacheManager将会自动作为缓存的实现。

(2)这是一个常规的 Ehcache配置文件,提供了两个缓存策略,一个是默认的,另一个名为 book_cache。具体参数作用如下:

name:缓存名称

maxElementsInMemory:缓存最大个数

eternal:缓存对象是否永久有效,一但设置了永久有效,timeout将不起作用。

timeToIdleSeconds:缓存对象在失效前的允许闲置时间(单位:秒)。仅当 eternal=false对象不是永久有效时,该属性才生效。默认值是0,也就是可闲置时间无穷大。

timeToLiveSeconds:缓存对象在失效前允许存活时间(单位:秒)。仅当 eternal=false 对象不是永久有效时,该属性才生效。默认值是 0,也就是存活时间无穷大。

overflowToDisk:表示内存中的数量达到 maxElementsInMemory时,Ehcache是否将对象写到磁盘中。

diskPersistent:是否缓存虚拟机重启期数据。

diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是 120秒。

(3)如果我们想要自定 Ehcache配置文件的名称和位置,可以在application.properties中添加如下配置:

spring.cache.ehcache.config=classpath:config/another-config.xml

maxElementsInMemory="10000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="false"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

/>

maxElementsInMemory="10000"

eternal="true"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

diskPersistent="true"

diskExpiryThreadIntervalSeconds="10"/>

3,开启缓存

在项目的入口类上添加 @EnableCaching 注解开启缓存,代码如下:

@SpringBootApplication

@EnableCaching

public class DemoApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context

= SpringApplication.run(DemoApplication.class, args);

}

}

4,开始测试

(1)首先我们创建一个 Book实体类:

@Setter

@Getter

@NoArgsConstructor

public class Book implements Serializable {

private Integer id;

private String name;

private String author;

}

(2)接着创建一个 BookDao并添加相关的缓存注解:

(1)在 BookDao上添加 @CacheConfig 注解指定使用的缓存的名字,这个配置可选。若不使用@CacheConfig注解,则直接在@Cacheable注解中指明缓存名字。

(2)在方法上添加 @Cacheable 注解表示对该方法进行缓存:

默认情况下,缓存的 key是方法的参数,缓存的 value是方法的返回值。

当开发者在其他类中调用该方法时,首先会根据调用参数查看缓存中是否有相关数据,若有则直接使用缓存数据,该方法不会执行。

否则执行该方法,执行成功后将返回值缓存起来。

但若是在当前类中调用该方法,则缓存不会生效。

(3)@Cacheable注解中还有一个属性 condition用来描述缓存的执行时机,例如:

@Cacheable(condition="#id%2-0")表示当 id对 2取模为 0 时才进行缓存,否则不缓存。

(4)如果开发者不想使用默认的 key,也可以像第 15行和第 22行一样自定义 key:

第 15 行表示缓存的 key为参数 book 对象中 id的值。

第 22行表示缓存的 key为参数 id。

(5)除了上面这种使用参数定义 key的方式之外,Spring还提供了一个 root对象用来生成 key。下面是一些用法实例:

#root.methodName:当前方法名

#root.method.name:当前方法对象

#root.caches[0].name:当前方法使用的缓存

#root.target:当前被调用的对象

#root.targetClass:当前被调用的对象的 class

#root.args[0]:当前方法参数数组

(6)@Cacheput注解一般用于数据更新方法上:

与 @Cacheable 注解不同,添加了@Cacheput注解的方法每次在执行时都不去检查缓存中是否有数据,而是直接执行方法,然后将方法的执行结果缓存起来。

如果该 key对应的数据已经被缓存起来了,就会覆盖之前的数据,这样可以避免再次加载数据时获取到脏数据。

同时,@Cacheput具有和 @Cacheable类似的属性,这里不再赘述。

(7)@CacheEvict注解一般用于删除方法上,表示移除一个 key对应的缓存。@CacheEvict 注解有两个特殊的属性 allEntries和 beforelnvocation:

allEntries 表示是否将所有的缓存数据都移除,默认为 false。

beforelnvocation表示是否在方法执行之前移除缓存中的数据,默认为 false,即在方法执行之后移除缓存中的数据。

@Repository

@CacheConfig(cacheNames = "book_cache")

public class BookDao {

@Cacheable

public Book getBookById(Integer id) {

System.out.println("getBookById");

Book book = new Book();

book.setId(id);

book.setName("三国演义");

book.setAuthor("罗贯中");

return book;

}

@CachePut(key = "#book.id")

public Book updateBookById(Book book) {

System.out.println("updateBookById");

book.setName("三国演义2");

return book;

}

@CacheEvict(key = "#id")

public void deleteBookById(Integer id) {

System.out.println("deleteBookById");

}

}

(3)创建一个测试 Controller对 BookDao中的方法进行测试:

@RestController

public class HelloController {

@Autowired

BookDao bookDao;

@GetMapping("/test")

public void test() {

// 连续获取两次数据

bookDao.getBookById(1);

bookDao.getBookById(1);

// 删除后再次获取数据

bookDao.deleteBookById(1);

Book b3 = bookDao.getBookById(1);

System.out.println("b3:"+b3);

// 更新后再次获取数据

Book b = new Book();

b.setName("平凡的世界");

b.setAuthor("路遥");

b.setId(1);

bookDao.updateBookById(b);

Book b4 = bookDao.getBookById(1);

System.out.println("b4:"+b4);

}

}

(4)访问这个接口,可以看到控制台打印日志如下:

一开始执行了两个査询,但是查询方法只打印了一次,因为第二次使用了缓存。

接下来执行了删除方法,删除方法执行完之后再次执行查询,查询方法又被执行了,因为在删除方法中缓存已经被删除了。

再接下来执行更新方法,更新方法中不仅更新数据,也更新了缓存,所以在最后的査询方法中,查询方法日志没打印,说明该方法没执行,而是使用了缓存中的数据,而缓存中的数据已经被更新了。

附:自定义缓存 key 的生成器 KeyGenerator

根据前面介绍可知,默认情况下缓存的 key是方法的参数。如果不想使用默认的 key,可以使用自定义 key(使用参数定义 key的方式、或者使用 root对象来生成 key)

如果这些 key不能满足开发需求,我们也可以自定义缓存 key的生成器 KeyGenerator

1,创建自定义 KeyGenerator

自定义的 MyKeyGenerator实现 KeyGenerator接口,然后实现该接口中的 generate方法。

generate方法的三个参数分别是:当前对象、当前请求的方法以及方法的参数,开发者可根据这些信息纽成一个新的 key返回,返回值就是缓存的 key。

@Component

public class MyKeyGenerator implements KeyGenerator {

@Override

public Object generate(Object target, Method method, Object... params) {

return Arrays.toString(params);

}

}

2,使用自定义的 KeyGenerator

使用时我们只需要在 @Cacheable 注解中引用 MyKeyGenermor实例即可。

@Repository

@CacheConfig(cacheNames = "book_cache")

public class BookDao {

@Autowired

MyKeyGenerator myKeyGenerator;

@Cacheable(keyGenerator = "myKeyGenerator")

public Book getBookById(Integer id) {

System.out.println("getBookById");

Book book = new Book();

book.setId(id);

book.setName("三国演义");

book.setAuthor("罗贯中");

return book;

}

}

ehchache验证缓存过期的api_SpringBoot - 缓存的使用详解1(使用Ehcache 2.x缓存)相关推荐

  1. Redis 缓存过期(maxmemory) 配置/算法 详解

    LRU(Least Recently Used) 最近最少使用算法是众多置换算法中的一种. Redis中有一个 maxmemory 概念,主要是为了将使用的内存限定在一个固定的大小.Redis 用到的 ...

  2. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解(1)

    大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...

  3. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    标签:读写分离 页面缓存 URL重写 Nginx 反向代理 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://freeloda.bl ...

  4. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解【转载】

    本文只为备份,以防失效.原文请看https://blog.51cto.com/freeloda/1288553 补充说明:部分图片为测试图片,未完全复制,参考文字描述即可. Nginx 反向代理.负载 ...

  5. Nginx反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...

  6. iOS教程:详解iOS多图下载的缓存机制

    ios教程,ios的干货一直来不及给大家分享,小编也是一直在忙啊!今天给大家献上ios:详解iOS多图下载的缓存机制 1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cel ...

  7. 三十七、缓存注解@Cacheable、@CacheEvict、@CachePut详解

    #        缓存注解@Cacheable.@CacheEvict.@CachePut详解 ##一.@Cacheable用法详解 ###1.用在哪里?     用在方法或者类上. ###2.这两种 ...

  8. petshop4.0 详解之四(PetShop之ASP.NET缓存)

    <p>如果对微型计算机硬件系统有足够的了解,那么我们对于Cache这个名词一定是耳熟能详的.在CPU以及主板的芯片中,都引入了这种名为高速缓冲存储器(Cache)的技术.因为Cache的存 ...

  9. php动态页面如何缓存,php缓存并压缩动态页面的技巧详解

    mod_gzip是一个Apache模块,其功能是使用Gzip压缩静态的html页面,遵循IETF标准的浏览器可以接受gzip编码(IE, Netscape等).mod_gzip可以将页面的下载时间提高 ...

最新文章

  1. SQL数据库入门基础
  2. HTML5 参数传递
  3. homebrew长时间停在Updating Homebrew 这个步骤
  4. 【安全牛学习笔记】抓包嗅探
  5. javascript this
  6. Huber Loss function
  7. 基于状态机的游戏框架
  8. python提供的内置函数有哪些_python内置函数介绍
  9. 兼容标准的CSV文件读写类
  10. 用“看板图”实现敏捷项目的可视化
  11. 大创和互联网加_大创?科研立项?互联网+大赛?创业大赛?……你还在纠结吗?...
  12. 机器人视觉硬件方案设计对比
  13. 指针式仪表自动读数与识别(四):非圆形表盘定位
  14. C++ 静态成员变量与静态成员函数
  15. 什么样的工作轻松又赚钱?真的有这样的工作吗?
  16. 传统隐私权及网络隐私权的界定
  17. LBP+SVM 活体识别
  18. 超级工程落户山东,用清洁能源解决30万人用电
  19. 俄罗斯主权因特网RuNet的特点
  20. 2022 OpenCV人工智能竞赛优秀项目团队介绍集锦(一)

热门文章

  1. CAD2020下载AutoCAD2020下载安装教程AutoCAD2020中文下载安装方法
  2. 33、基于CACX和R7F0C004M的瑞萨单片机入门教程
  3. python推荐算法课程_Python数据科学:全栈技术详解4-推荐算法
  4. 编程猫创作工具:新版Kitten新体验
  5. 浅淡测试夹具制作的制作策略
  6. 腾讯员工绩效被打2星,情绪接近崩溃!大厂“内卷”太凶残......
  7. 灵信视觉led。六代卡和五代卡
  8. Nginx 根据手机电脑进行不同跳转
  9. 我6个月的学习编程经历:从”大齿怪“到“狂欢者”
  10. 天翼云网站访问不了解决办法