前言

当多次查询数据库影响到系统性能的时候,可以考虑使用缓存,来解决数据访问新能的问题。
SpringBoot 已经为我们提供了自动配置多个 CacheManager 的实现,只要去实现使用它就可以了。

一般的系统都是优先使用 EhCache,它工作在 JAVA 进程中,在传统的应用没有太大要求的时候,使用它比较方便,分布式系统中去使用 Shiro 集中管理缓存。

正文

加入依赖

在 pom.xml 中加入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency>

添加缓存相关的配置

新建 ehcache.xml,加入缓存相关参数, 我新添加一个 name 为 users 的缓存设置:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false"><diskStore path="java.io.tmpdir/Tmp_EhCache"/><defaultCachemaxElementsInMemory="1000"maxEntriesLocalHeap="400"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="false"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"/><cachename="users"maxEntriesLocalHeap="200"timeToLiveSeconds="600"/></ehcache>

参数详解:

  • name:缓存名称。
  • maxElementsInMemory:缓存最大个数。
  • eternal:对象是否永久有效,一但设置了,timeout将不起作用。
  • timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  • timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
  • overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
  • diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  • maxElementsOnDisk:硬盘最大缓存个数。
  • diskPersistent:是否缓存虚拟机重启期数据,默认为false。
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
  • clearOnFlush:内存数量最大时是否清除。
  • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。

开启缓存

  1. 在系统配置文件中指定
    在配置文件中加入指定我们设置的 ehcache.xml 作为 EhCache 的配置文件:
spring:cache:ehcache:config: config/ehcache.xml # 指定 ehcache.xml 创建EhCache的缓存管理器type: ehcache # 指定缓存管理器
  1. 在启动类上加上注解 @EnableCaching,开启缓存。

使用

使用的时候需要注意,我们之前在 shiro 缓存中 配置了相关的缓存的配置,现在需要把 shiro 相关的缓存的内容全部都要删除掉,不然两者的缓存会存在冲突。
还是以 shiro 的获取权限列表的服务为例,不用 shiro-cache 后,直接在查询的这里自己添加上缓存就可以了。

@CacheConfig(cacheNames = "users")
public interface ShiroService {/*** 获取用户权限** @param userId 用户ID* @return 权限*/@CacheableSet<String> getUserPermissions(long userId);

debug 调试,

@Autowired
private CacheManager cacheManager;

发现 key 为 users 中存储了相关内容。

注解的使用

  • @CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义。

  • @Cacheable:配置了

    getUserPermissions(long userId)
    

    函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:

    1. valuecacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了。
    2. key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
    3. condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,
    4. unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
    5. keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
    6. cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用。
    7. cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。

除了这里用到的两个注解之外,还有下面几个核心注解:
* @CachePut:配置于函数上,能够根据参数定义条件来进行缓存,它与@Cacheable不同的是,它每次都会真是调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析
* @CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable一样的参数之外,它还有下面两个参数:

  1. allEntries:非必需,默认为false。当为true时,会移除所有数据
  2. beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。

缓存配置

在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者:

  1. Generic
  2. JCache (JSR-107)
  3. EhCache 2.x
  4. Hazelcast
  5. Infinispan
  6. Redis
  7. Guava
  8. Simple

通常还是推荐去指定一个 缓存类型比较好,在系统配置文件配置:

spring:cache:type: ehcache

参考文章

  • Spring Boot中的缓存支持(一)注解配置与EhCache使用

学习Spring Boot:(二十一)使用 EhCache 实现数据缓存相关推荐

  1. 学习Spring Boot:(二十五)使用 Redis 实现数据缓存

    前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis. 正文 当应用程序 ...

  2. 学习Spring Boot:(二十六)使用 RabbitMQ 消息队列

    前言 前面学习了 RabbitMQ 基础,现在主要记录下学习 Spring Boot 整合 RabbitMQ ,调用它的 API ,以及中间使用的相关功能的记录. 相关的可以去[我的博客/Rabbit ...

  3. quartz集成到springboot_一个用来学习 spring boot 的开源项目,总共包含 57 个集成demo...

    spring-boot-demo 一个用来学习 spring boot 的项目,总共包含 57 个集成demo. 包含集成 actuator(监控).admin(可视化监控).logback(日志). ...

  4. 线程本地存储器——Windows核心编程学习手札之二十一

    线程本地存储器 --Windows核心编程学习手札之二十一 C/C++运行期库使用线程本地存储器,运行期库是在多线程应用程序出现前设计的,因此运行期库里的大多数函数是用于单线程应用程序的.函数strt ...

  5. OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十

    OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...

  6. springboot 拦截器 日志_跟武哥一起学习Spring Boot,一份全面详细的学习教程

    SpringBoot现在已经是企业开发项目的标准框架,至少新项目一般都会使用SpringBoot框架,发现有一个SpringBoot的笔记写的非常好,非常全面, 也非常认真,即使你对SpringBoo ...

  7. 2小时学习Spring Boot 2019版本 代码一样推送至github上面去

    简介:<2小时学习Spring Boot>后续进阶课程,主要讲述了Spring Boot针对Web方面的相关技巧 讲师实战课程<Spring Boot微信点餐系统> http: ...

  8. 学习Spring Boot:(一)入门

    微服务 微服务其实是服务化思路的一种最佳实践方向,遵循SOA(面向服务的架构)的思路,各个企业在服务化治理上面的道路已经走得很远了,整个软件交付链上各个环节的基础设施逐渐成熟了,微服务就诞生了. 微服 ...

  9. Spring Boot(二):Web 综合开发

    Spring Boot(二):Web 综合开发 上篇文章介绍了 Spring Boot 初级教程:Spring Boot(一):入门篇,方便大家快速入门.了解实践 Spring Boot 特性:本篇文 ...

最新文章

  1. asp.net core学习笔记
  2. VTK:隐式球体用法实战
  3. 好用的记事本_推荐一款可设定定时提醒的电脑桌面悬挂记事本便签软件
  4. java 实现 常见排序算法(三)快速排序
  5. C语言:fopen与open的总结
  6. 基于MaxCompute 衣二三帮助客户找到合适自己的衣服
  7. 前端windows下常用的CMD 命令归纳
  8. 【kafka】kafka 控制台 消费 ip 却找 域名 报错 Can‘t resolve address UnresolvedAddressException
  9. 最长不下降子序列的长度
  10. 8. 字符串转整数 (atoi)
  11. CMD 命令 复制多级子目录特定文件
  12. 开发者的固化思维及解决办法
  13. 数字信号处理之均值、方差、均方值、均方差计算和它们的物理意义
  14. c语言博物馆文物管理系统,博物馆文物智能管理系统.docx
  15. POI 操作word
  16. 容器亲和、反亲和、污点、容忍以及驱逐的介绍
  17. php7.1 rc,解决Windows上编译PHP7.1拓展的错误
  18. Prometheus监控(一)
  19. 贴片电阻0805 0603 1206分装是什么意思
  20. c全日制聋校实验教材语言训练教参小学1册,聋哑学校课程设置建议(2)

热门文章

  1. opencv机器学习线性回归_机器学习(线性回归(二))
  2. [转载] java对象在内存中的结构
  3. java treemap_Java TreeMap firstEntry()方法及示例
  4. kotlin中既继承又实现_Kotlin程序| 解决继承中的主要冲突的示例
  5. linux服务chm,linux系统服务 chm
  6. python爬虫requests源码链家_Python爬虫之---爬链家
  7. Java BigDecimal toString()方法与示例
  8. c ++查找字符串_C ++类和对象| 查找输出程序| 套装1
  9. Java 中 10 大坑爹功能!
  10. vb中picturebox透明时看到下面的picturebox中图片