为了提高性能,减少数据库的压力,使用缓存是非常好的手段之一。本文,讲解 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. Github SSH key 的配置

    哈喽,新年好呀! 今天我又来更新一点github的内容啦~~ windows版本 一.打开git shell,输入指令操作ssh-keygen -t rsa -C “你的注册邮箱”,然后回车回车回车, ...

  2. python中eval()和json.dumps的使用

    在python中通过requests.get(url)获取json数据,此时可能需要eval进行解析. # -*- coding: utf-8 -*- import requests r = requ ...

  3. 使用Spring-data-jpa(1)(三十)

    在实际开发过程中,对数据库的操作无非就“增删改查”.就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写大量类似而枯燥的语句来完成业务逻辑. 为了解决这些大量枯燥的数据操作语句 ...

  4. Java逻辑

    1.开发简单Java应用程序 1-1:什么是程序 程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合.1-2:为什么学习Java Java是现在的主流1-3:Java可以做什么 ...

  5. Oracle中如何停止正在执行SQL语句

    oracle的用P/SQL客户端中,如何停止正在执行的SQL语句? 我们使用oracle语句查询某个表时,如果查询的表数据太多,如何停止正在执行操作 如查询的表数据超过上万条时,如何停止查询操作

  6. Shell编程积累 zhuan

    在新的shell里执行程序 cd /home/lq/Server/anew-lstm_scriptmatlab -nodesktop -singleCompThred -r 'aStart' ,qui ...

  7. 用socket.io将Node后台与M站相联系

      目的:用socket.io将Node后台与M站相联系,实现当Node后台添加一条数据时,调用该接口的M站不用手动刷新自动出现新增的数据     具体实现:当在后台系统position列表中添加/修 ...

  8. mybatis-ResultMappingResolver类信息

    ResultMappingResolver类介绍 一个ResultMap元素对应一个ResultMap对象 resultMap元素中的idArg/result/association/collecti ...

  9. json模块&xml

    json模块将数据修改成字符串,方便其他语言进行识别. 只认双引号,不认单引号.使用json.dumps的操作步骤 先将单引号修改成单引号 将变量使用单引号引起来 将数据类型编程json字符串 jso ...

  10. Win10系列:JavaScript综合实例1

    上面几个小节讲解了使用HTML5和JavaScript语言开发Windows 应用商店应用时会用到的一些技术,本小节将前面介绍的知识融合在一起创建一个菜谱应用程序,帮助读者更进一步地理解和掌握这些知识 ...