为了提高性能,减少数据库的压力,使用缓存是非常好的手段之一。本文,讲解 Spring Boot 如何集成缓存管理。

声明式缓存

Spring 定义 CacheManager 和 Cache 接口用来统一不同的缓存技术。例如 JCache、 EhCache、 Hazelcast、 Guava、 Redis 等。在使用 Spring 集成 Cache 的时候,我们需要注册实现的 CacheManager 的 Bean。

Spring Boot默认集成CacheManager

Spring Boot 为我们自动配置了多个 CacheManager 的实现。

Spring Boot 为我们自动配置了 JcacheCacheConfiguration、 EhCacheCacheConfiguration、HazelcastCacheConfiguration、GuavaCacheConfiguration、RedisCacheConfiguration、SimpleCacheConfiguration 等。

默认的 ConcurrenMapCacheManager

Spring 从 Spring3.1 开始基于 java.util.concurrent.ConcurrentHashMap 实现的缓存管理器。所以, Spring Boot 默认使用 ConcurrentMapCacheManager 作为缓存技术。

以下是我们不引入其他缓存依赖情况下,控制台打印的日志信息。

  1. Bean 'cacheManager' of type [class org.springframework.cache.concurrent.ConcurrentMapCacheManager]

实战演练

Maven 依赖

首先,我们先创建一个 POM 文件。

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <parent>
  5. <groupId>org.springframework.boot</groupId>
  6. <artifactId>spring-boot-starter-parent</artifactId>
  7. <version>1.3.3.RELEASE</version>
  8. </parent>
  9. <groupId>com.lianggzone.demo</groupId>
  10. <artifactId>springboot-action-cache</artifactId>
  11. <version>0.1</version>
  12. <packaging>jar</packaging>
  13. <name>springboot-action-cache</name>
  14. <dependencies>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter-web</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-cache</artifactId>
  26. </dependency>
  27. </dependencies>
  28. <build>
  29. <plugins>
  30. <plugin>
  31. <groupId>org.apache.maven.plugins</groupId>
  32. <artifactId>maven-compiler-plugin</artifactId>
  33. <configuration>
  34. <defaultLibBundleDir>lib</defaultLibBundleDir>
  35. <source>1.7</source>
  36. <target>1.7</target>
  37. <encoding>UTF-8</encoding>
  38. </configuration>
  39. </plugin>
  40. <plugin>
  41. <groupId>org.apache.maven.plugins</groupId>
  42. <artifactId>maven-resources-plugin</artifactId>
  43. <configuration>
  44. <encoding>UTF-8</encoding>
  45. <useDefaultDelimiters>false</useDefaultDelimiters>
  46. <escapeString>\</escapeString>
  47. <delimiters>
  48. <delimiter>${*}</delimiter>
  49. </delimiters>
  50. </configuration>
  51. </plugin>
  52. <plugin>
  53. <groupId>org.springframework.boot</groupId>
  54. <artifactId>spring-boot-maven-plugin</artifactId>
  55. </plugin>
  56. </plugins>
  57. </build>
  58. </project>

其中,最核心的是添加 spring-boot-starter-cache 依赖。

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>

开启缓存支持

在 Spring Boot 中使用 @EnableCaching 开启缓存支持。

  1. @Configuration
  2. @EnableCaching
  3. public class CacheConfiguration {}

服务层

创建一个服务类

  1. @Service("concurrenmapcache.cacheService")
  2. public class CacheService {
  3. }

首先,我们先来讲解下 @Cacheable 注解。@Cacheable 在方法执行前 Spring 先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存。有两个重要的值, value,返回的内容将存储在 value 定义的缓存的名字对象中。key,如果不指定将使用默认的 KeyGenerator 生成。

我们在查询方法上,添加 @Cacheable 注解,其中缓存名称为 concurrenmapcache。

  1. @Cacheable(value = "concurrenmapcache")
  2. public long getByCache() {
  3. try {
  4. Thread.sleep(3 * 1000);
  5. } catch (InterruptedException e) {
  6. e.printStackTrace();
  7. }
  8. return new Timestamp(System.currentTimeMillis()).getTime();
  9. }

@CachePut 与 @Cacheable 类似,但是它无论什么情况,都会将方法的返回值放到缓存中, 主要用于数据新增和修改方法。

  1. @CachePut(value = "concurrenmapcache")
  2. public long save() {
  3. long timestamp = new Timestamp(System.currentTimeMillis()).getTime();
  4. System.out.println("进行缓存:" + timestamp);
  5. return timestamp;
  6. }

@CacheEvict 将一条或多条数据从缓存中删除, 主要用于删除方法,用来从缓存中移除相应数据。

  1. @CacheEvict(value = "concurrenmapcache")
  2. public void delete() {
  3. System.out.println("删除缓存");
  4. }

控制层

为了展现效果,我们先定义一组简单的 RESTful API 接口进行测试。

  1. @RestController("concurrenmapcache.cacheController")
  2. @RequestMapping(value = "/concurrenmapcache/cache")
  3. public class CacheController {
  4. @Autowired
  5. private CacheService cacheService;
  6. /**
  7. * 查询方法
  8. */
  9. @RequestMapping(value = "", method = RequestMethod.GET)
  10. public String getByCache() {
  11. Long startTime = System.currentTimeMillis();
  12. long timestamp = this.cacheService.getByCache();
  13. Long endTime = System.currentTimeMillis();
  14. System.out.println("耗时: " + (endTime - startTime));
  15. return timestamp+"";
  16. }
  17. /**
  18. * 保存方法
  19. */
  20. @RequestMapping(value = "", method = RequestMethod.POST)
  21. public void save() {
  22. this.cacheService.save();
  23. }
  24. /**
  25. * 删除方法
  26. */
  27. @RequestMapping(value = "", method = RequestMethod.DELETE)
  28. public void delete() {
  29. this.cacheService.delete();
  30. }
  31. }

运行

  1. @RestController
  2. @EnableAutoConfiguration
  3. @ComponentScan(basePackages = { "com.lianggzone.springboot" })
  4. public class WebMain {
  5. public static void main(String[] args) throws Exception {
  6. SpringApplication.run(WebMain.class, args);
  7. }
  8. }

课后作业

我们分为几个场景进行测试。

  • 多次调用查询接口,查看缓存信息是否变化,控制台日志是否如下?你得到的结论是什么?
  • 调用保存接口,再调用查询接口,查看缓存信息是否变化?你得到的结论是什么?
  • 调用删除接口,再调用查询接口,接口响应是否变慢了?你再看看控制台日志,你得到的结论是什么?

扩展阅读

如果想更深入理解 Spring 的 Cache 机制,这边推荐两篇不错的文章。

源代码

相关示例完整代码: springboot-action

(完)

如果觉得我的文章对你有帮助,请随意打赏。

Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门的更多相关文章

  1. Spring Boot 揭秘与实战(二) 数据缓存篇 - Redis Cache

    文章目录 1. Redis Cache 集成 2. 源代码 本文,讲解 Spring Boot 如何集成 Redis Cache,实现缓存. 在阅读「Spring Boot 揭秘与实战(二) 数据缓存 ...

  2. Spring Boot 揭秘与实战(二) 数据缓存篇 - Guava Cache

    文章目录 1. Guava Cache 集成 2. 个性化配置 3. 源代码 本文,讲解 Spring Boot 如何集成 Guava Cache,实现缓存. 在阅读「Spring Boot 揭秘与实 ...

  3. Spring Boot 揭秘与实战(二) 数据缓存篇 - EhCache

    文章目录 1. EhCache 集成 2. 源代码 本文,讲解 Spring Boot 如何集成 EhCache,实现缓存. 在阅读「Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门 ...

  4. Spring Boot 揭秘与实战(二) 数据存储篇 - 声明式事务管理

    文章目录 1. 声明式事务 2. Spring Boot默认集成事务 3. 实战演练4. 源代码 3.1. 实体对象 3.2. DAO 相关 3.3. Service 相关 3.4. 测试,测试 本文 ...

  5. Spring Boot 揭秘与实战(二) 数据存储篇 - ElasticSearch

    文章目录 1. 版本须知 2. 环境依赖 3. 数据源 3.1. 方案一 使用 Spring Boot 默认配置 3.2. 方案二 手动创建 4. 业务操作5. 总结 4.1. 实体对象 4.2. D ...

  6. Spring Boot 揭秘与实战(二) 数据存储篇 - MongoDB

    文章目录 1. 环境依赖 2. 数据源 2.1. 方案一 使用 Spring Boot 默认配置 2.2. 方案二 手动创建 3. 使用mongoTemplate操作4. 总结 3.1. 实体对象 3 ...

  7. Spring Boot 揭秘与实战(二) 数据存储篇 - Redis

    文章目录 1. 环境依赖 2. 数据源 2.1. 方案一 使用 Spring Boot 默认配置 2.2. 方案二 手动创建 3. 使用 redisTemplate 操作4. 总结 3.1. 工具类 ...

  8. Spring Boot 揭秘与实战(二) 数据存储篇 - JPA整合

    文章目录 1. 环境依赖 2. 数据源 3. 脚本初始化 4. JPA 整合方案一 通过继承 JpaRepository 接口 4.1. 实体对象 4.2. DAO相关 4.3. Service相关 ...

  9. Spring Boot 揭秘与实战(二) 数据存储篇 - MyBatis整合

    文章目录 1. 环境依赖 2. 数据源3. 脚本初始化 2.1. 方案一 使用 Spring Boot 默认配置 2.2. 方案二 手动创建 4. MyBatis整合5. 总结 4.1. 方案一 通过 ...

随机推荐

  1. 有史以来性价比最高最让人感动的一次数据库&amp;SQL优化(DB &amp; SQL TUNING)——半小时性能提升千倍

    昨天,一个客户现场人员急急忙忙打电话找我,说需要帮忙调优系统,因为经常给他们干活,所以,也就没多说什么,先了解情况,据他们说,就是他们的系统最近才出现了明显的反应迟钝问题,他们的那个系统我很了解,软硬 ...

  2. QPainter使用不同风格的QBrush来填充区域

    效果图: void WgtText::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QP ...

  3. 部署Linux项目

    部署Linux项目   1● 下载软件 ftp       安装 2● 创建连接 3● java项目   gunzip –c *.gz tar –xzf *.gz       rm –rf rm -r ...

  4. 逆袭之旅DAY24.XIA.二重进阶、双色球

    一. 选择题. 1. 以下关于二重循环的说法正确的是(D). A. 二重循环就是一般程序中只能有两个循环 B. While循环不能嵌套在for循环里 C. 两个重叠的循环不能嵌套在第三个循环里. D. ...

  5. python 自然语言处理(四)____词典资源

    词典或者词典资源是一个词和/或短语及其相关信息的集合,例如:词性和词意定义等相关信息.词典资源附属于文本,而且通常在文本的基础上创建和丰富.下面列举几种nltk中的词典资源. 1. 词汇列表语料库 n ...

  6. poj1226

    题解: 后缀数组 把所有串先翻转,用一个没有出现过的字符连接 然后再把所有串接起来 然后用一个没有出现过的字符连接 然后二分 在后缀数组上判断lcp 代码: #include<cstdio> ...

  7. nginx:负载均衡(三)分流策略

    [1]轮询策略.轮询策略是最简单的策略,无脑配置,不考虑服务器的访问的能力.每个请求按照时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除 upstream www.daysn. ...

  8. flask项目结构(四)使用sqlalchemy和alembic

    简介 其实我不是啥正经人,错了,不是啥正经程序员,所能想到的估计也就码农一级吧,高级程序员,搞什么算法,什么人工智能,大数据计算…………离我还太遥远. 但是这并不妨碍我继续学习,继续写垃圾小程序. 反 ...

  9. TensorFlow学习笔记——节点(constant、placeholder、Variable)

    一. constant(常量) constant是TensorFlow的常量节点,通过constant方法创建,其是计算图(Computational Graph)中的起始节点,是传入数据. 创建方式 ...

  10. 查看json数据更新情况

    #! python3 # -*- coding:utf8 -*- #主要为读取excel中接口地址,打开网页爬取url页面中数据,解析json,检查是否符合逻辑(正常) import requests ...