boot 版本 2.4.13 boot Caching 官方文档 其他实战笔记参考

系统的知识后面有实际再补,先看如何接入使用

Ehcache 2.x 使用

添加依赖

  1. // ~ cache==========================
  2. // ehcache3 更规范,要求有序列化,相对来说比较难用
  3. implementation 'org.springframework.boot:spring-boot-starter-cache:2.4.13'
  4. implementation 'net.sf.ehcache:ehcache'

编写 ehcache.xml 文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache>
  3. <!-- 当你缓存大量数据的时候,请自行创建自己的缓存配置-->
  4. <!-- 指定一个文件目录,当 EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 -->
  5. <diskStore path="java.io.tmpdir/ehcache"/>
  6. <!--
  7. 缓存配置
  8. name:缓存名称。
  9. maxElementsInMemory:缓存最大个数。
  10. eternal:对象是否永久有效,一但设置了,timeout将不起作用。
  11. timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  12. timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
  13. overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
  14. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  15. maxElementsOnDisk:硬盘最大缓存个数。
  16. diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
  17. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  18. memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
  19. clearOnFlush:内存数量最大时是否清除。
  20. -->
  21. <!--注意:由于是公共的缓存管理器,在使用 @Cacheable 的时候请让自己的 key 唯一,最好是类名+方法名+业务键 -->
  22. <!-- 设定缓存的默认数据过期策略 -->
  23. <defaultCache
  24. maxElementsInMemory="10000"
  25. eternal="false"
  26. overflowToDisk="true"
  27. timeToIdleSeconds="10"
  28. timeToLiveSeconds="20"
  29. diskPersistent="false"
  30. diskExpiryThreadIntervalSeconds="120"/>
  31. <!-- 由于本项目的场景基本上都是缓存大量全局数据,闲置和过期时间都可以变得较大 -->
  32. <cache name="common:cache:2m"
  33. maxElementsInMemory="100000"
  34. eternal="false"
  35. overflowToDisk="false"
  36. timeToIdleSeconds="90"
  37. timeToLiveSeconds="180"
  38. />
  39. <cache name="common:cache:5m"
  40. maxElementsInMemory="100000"
  41. eternal="false"
  42. overflowToDisk="false"
  43. timeToIdleSeconds="150"
  44. timeToLiveSeconds="300"
  45. />
  46. <cache name="common:cache:10m"
  47. maxElementsInMemory="100000"
  48. eternal="false"
  49. overflowToDisk="false"
  50. timeToIdleSeconds="300"
  51. timeToLiveSeconds="600"/>
  52. <cache name="common:cache:20m"
  53. maxElementsInMemory="100000"
  54. eternal="false"
  55. overflowToDisk="false"
  56. timeToIdleSeconds="600"
  57. timeToLiveSeconds="1200"/>
  58. <cache name="common:cache:30m"
  59. maxElementsInMemory="100000"
  60. eternal="false"
  61. overflowToDisk="false"
  62. timeToIdleSeconds="900"
  63. timeToLiveSeconds="1800"/>
  64. <cache name="common:cache:1h"
  65. maxElementsInMemory="100000"
  66. eternal="false"
  67. overflowToDisk="false"
  68. timeToIdleSeconds="1800"
  69. timeToLiveSeconds="3600"/>
  70. <cache name="common:cache:2h"
  71. maxElementsInMemory="100000"
  72. eternal="false"
  73. overflowToDisk="false"
  74. timeToIdleSeconds="3600"
  75. timeToLiveSeconds="7200"/>
  76. <!-- 后面的的为单独的业务模块声明的 cache 配置 -->
  77. <!-- token 发放缓存 -->
  78. <cache name="accessTokenGrant:cache:30m"
  79. maxElementsInMemory="1000000"
  80. eternal="false"
  81. overflowToDisk="false"
  82. timeToIdleSeconds="900"
  83. timeToLiveSeconds="1800"
  84. />
  85. <!-- 用户信息缓存 发放缓存 -->
  86. <cache name="userinfo:cache:5m"
  87. maxElementsInMemory="100000"
  88. eternal="false"
  89. overflowToDisk="false"
  90. timeToIdleSeconds="150"
  91. timeToLiveSeconds="300"
  92. />
  93. </ehcache>

编写自动配置类,其实最组主要的是声明 @EnableCaching注解,关于 EhCacheNames 这是声明公用的 cache name

  1. package cn.mrcode.autoconfig;
  2. import org.springframework.cache.annotation.EnableCaching;
  3. import org.springframework.context.annotation.Configuration;
  4. /**
  5. * <pre>
  6. * 全局公共缓存配置,这里只是针对一些公共的配置进行了 type 类型的配置;
  7. *
  8. * 如果你有大量数据进行缓存时,请创建自己的缓存
  9. * </pre>
  10. *
  11. * @author mrcode
  12. */
  13. @EnableCaching
  14. @Configuration
  15. public class CacheManagerConfig {
  16. /**
  17. * <pre>
  18. * 这里的缓存都是最大存活时间,闲置时间是存活时间的一半
  19. * 闲置不使用则自动被驱逐
  20. * </pre>
  21. */
  22. public interface EhCacheNames {
  23. /**
  24. * 2 分钟缓存组
  25. */
  26. String CACHE_COMMON_2MINS = "common:cache:2m";
  27. /**
  28. * 5 分钟缓存组
  29. */
  30. String CACHE_COMMON_5MINS = "common:cache:5m";
  31. /**
  32. * 10 分钟缓存组
  33. */
  34. String CACHE_COMMON_10MINS = "common:cache:10m";
  35. /**
  36. * 20 分钟缓存组
  37. */
  38. String CACHE_COMMON_20MINS = "common:cache:20m";
  39. /**
  40. * 30 分钟缓存组
  41. */
  42. String CACHE_COMMON_30MINS = "common:cache:30m";
  43. /**
  44. * 1 小时缓存组
  45. */
  46. String CACHE_COMMON_1HOUR = "common:cache:1h";
  47. /**
  48. * 2 小时缓存组
  49. */
  50. String CACHE_COMMON_2HOUR = "common:cache:2h";
  51. }
  52. }

applicathion.yml 指定 cache 类型和配置文件

  1. spring:
  2. cache:
  3. type: ehcache
  4. ehcache:
  5. config: classpath:/ehcache.xml

然后就可以开始使用了

  1. import org.springframework.cache.annotation.CachePut;
  2. import org.springframework.cache.annotation.Cacheable;
  3. import org.springframework.stereotype.Service;
  4. import cn.mrcode.cachepdp.eshop.cache.model.ProductInfo;
  5. import cn.mrcode.cachepdp.eshop.cache.service.CacheService;
  6. @Service
  7. public class CacheServiceImpl implements CacheService {
  8. public static final String CACHE_NAME = "local";
  9. /**
  10. * 将商品信息保存到本地缓存中
  11. */
  12. @CachePut(value = CACHE_NAME, key = "'key_'+#productInfo.getId()")
  13. public ProductInfo saveLocalCache(ProductInfo productInfo) {
  14. return productInfo;
  15. }
  16. /**
  17. * 从本地缓存中获取商品信息
  18. */
  19. @Cacheable(value = CACHE_NAME, key = "'key_'+#id")
  20. public ProductInfo getLocalCache(Long id) {
  21. return null;
  22. }
  23. }
  24. m

对于这个 key 的定义来说,还可以使用 SpEL 表达式,比如下面这个

  1. @Cacheable(cacheNames = CACHE_COMMON_2MINS, key = "#root.targetClass + '_'+ #root.method + '_' + #brand")
  2. public MlsBrands getByNameForCache(String brand) {
  3. return getByName(brand);
  4. }
  • root.targetClass:表示获取当前类路径类名
  • root.method:当前方法名称,在这里是 getByNameForCache
  • 后面没有加 root 的表示从参数中获取,这里就是 brand 这个字符串的入参的值,比如传递 a,那么就是 a

key:表示存储的时候,缓存的 key 是什么。