概述

在如今高并发的互联网应用中,缓存的地位举足轻重,对提升程序性能帮助不小。而 3.x开始的 Spring也引入了对 Cache的支持,那对于如今发展得如火如荼的 Spring Boot来说自然也是支持缓存特性的。当然 Spring Boot默认使用的是 SimpleCacheConfiguration,即使用 ConcurrentMapCacheManager 来实现的缓存。但本文将讲述如何将 Guava Cache缓存应用到 Spring Boot应用中。

Guava Cache是一个全内存的本地缓存实现,而且提供了线程安全机制,所以特别适合于代码中已经预料到某些值会被多次调用的场景

下文就上手来摸一摸它,结合对数据库的操作,我们让 Guava Cache作为本地缓存来看一下效果!

注: 本文首发于 My Personal Blog:CodeSheep·程序羊,欢迎光临 小站


准备工作

  • 准备好数据库和数据表并插入相应实验数据(MySQL)

比如我这里准备了一张用户表,包含几条记录:

我们将通过模拟数据库的存取操作来看看 Guava Cache缓存加入后的效果。


搭建工程:Springboot + MyBatis + MySQL + Guava Cache

pom.xml 中添加如下依赖:

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--for mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!--for Mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- Spring boot Cache--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!--for guava cache--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>27.0.1-jre</version></dependency></dependencies>

建立 Guava Cache配置类

引入 Guava Cache的配置文件 GuavaCacheConfig

@Configuration
@EnableCaching
public class GuavaCacheConfig {@Beanpublic CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager();cacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).maximumSize(1000));return cacheManager;}
}

Guava Cache配置十分简洁,比如上面的代码配置缓存存活时间为 10 秒,缓存最大数目为 1000 个


配置 application.properties

server.port=82# Mysql 数据源配置
spring.datasource.url=jdbc:mysql://121.116.23.145:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver# mybatis配置
mybatis.type-aliases-package=cn.codesheep.springbt_guava_cache.entity
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

编写数据库操作和 Guava Cache缓存的业务代码

  • 编写 entity
public class User {private Long userId;private String userName;private Integer userAge;public Long getUserId() {return userId;}public void setUserId(Long userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public Integer getUserAge() {return userAge;}public void setUserAge(Integer userAge) {this.userAge = userAge;}
}
  • 编写 mapper
public interface UserMapper {List<User> getUsers();int addUser(User user);List<User> getUsersByName( String userName );
}
  • 编写 service
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> getUsers() {return userMapper.getUsers();}public int addUser( User user ) {return userMapper.addUser(user);}@Cacheable(value = "user", key = "#userName")public List<User> getUsersByName( String userName ) {List<User> users = userMapper.getUsersByName( userName );System.out.println( "从数据库读取,而非读取缓存!" );return users;}
}

看得很明白了,我们在 getUsersByName接口上添加了注解:@Cacheable。这是 缓存的使用注解之一,除此之外常用的还有 @CachePut@CacheEvit,分别简单介绍一下:

  1. @Cacheable:配置在 getUsersByName方法上表示其返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问
  2. @CachePut:配置于方法上时,能够根据参数定义条件来进行缓存,其与 @Cacheable不同的是使用 @CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中,所以主要用于数据新增和修改操作上
  3. @CacheEvict:配置于方法上时,表示从缓存中移除相应数据。
  • 编写 controller
@RestController
public class UserController {@Autowiredprivate UserService userService;@AutowiredCacheManager cacheManager;@RequestMapping( value = "/getusersbyname", method = RequestMethod.POST)public List<User> geUsersByName( @RequestBody User user ) {System.out.println( "-------------------------------------------" );System.out.println("call /getusersbyname");System.out.println(cacheManager.toString());List<User> users = userService.getUsersByName( user.getUserName() );return users;}}

改造 Spring Boot应用主类

主要是在启动类上通过 @EnableCaching注解来显式地开启缓存功能

@SpringBootApplication
@MapperScan("cn.codesheep.springbt_guava_cache")
@EnableCaching
public class SpringbtGuavaCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringbtGuavaCacheApplication.class, args);}
}

最终完工的整个工程的结构如下:


实际实验

通过多次向接口 localhost:82/getusersbyname POST数据来观察效果:

可以看到缓存的启用和失效时的效果如下所示(上文 Guava Cache的配置文件中设置了缓存 user的实效时间为 10s):

怎么样,缓存的作用还是很明显的吧!


后 记

由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!

  • My Personal Blog:CodeSheep 程序羊
  • 程序羊的 2018年终总(gen)结(feng)


Guava Cache本地缓存在 Spring Boot应用中的实践相关推荐

  1. spring boot 项目源码_Spring Boot2 系列教程(三)理解 Spring Boot 项目中的 parent

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent><groupId& ...

  2. Spring Boot 配置中的敏感信息如何保护?

    在之前的系列教程中,我们已经介绍了非常多关于Spring Boot配置文件中的各种细节用法,比如:参数间的引用.随机数的应用.命令行参数的使用.多环境的配置管理等等. 这些配置相关的知识都是Sprin ...

  3. 在Spring Boot测试中使用Testcontainer进行数据库集成测试

    在此博客文章中,我想演示如何在Spring Boot测试中集成Testcontainer以便与数据库一起运行集成测试. 我没有使用Testcontainers的Spring Boot模块. 如何与他们 ...

  4. Spring Boot 架构中的国际化支持实践—— Spring Boot 全球化解决方案

    背景 Spring Boot 主要通过 Maven 或 Gradle 这样的构建系统以继承方式添加依赖,同时继承了 Spring 框架中的优秀元素,减少了 Spring MVC 架构中的复杂配置,内置 ...

  5. 在Spring Boot项目中使用Spock框架

    转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...

  6. scheduled每天下午1点执行一次_在Spring Boot项目中使用@Scheduled注解实现定时任务...

    在java开发中定时任务的实现有多种方式,jdk有自己的定时任务实现方式,很多框架也有定时任务的实现方式.这里,我介绍一种很简单的实现方式,在Spring Boot项目中使用两个注解即可实现. 在sp ...

  7. Spring Boot JPA 中transaction的使用

    文章目录 @Transactional的实现 @Transactional的使用 Transaction的传播级别 REQUIRED SUPPORTS MANDATORY NEVER NOT_SUPP ...

  8. Spring Boot JPA中关联表的使用

    文章目录 添加依赖 构建Entity 构建Repository 构建初始数据 测试 Spring Boot JPA中关联表的使用 本文中,我们会将会通过一个Book和Category的关联关系,来讲解 ...

  9. Spring Boot JPA中使用@Entity和@Table

    文章目录 默认实现 使用@Table自定义表格名字 在JPQL Queries中重写表格名字 Spring Boot JPA中使用@Entity和@Table 本文中我们会讲解如何在Spring Bo ...

最新文章

  1. 爱情,没有对不起;只有不珍惜……[
  2. Class.getResource()、ClassLoader.getResource()和this.class.getClassLoader()解析
  3. LeetCode 738. 单调递增的数字(贪心)
  4. 饼图大小调整_这么漂亮的双层饼图,你会做吗?让你工作汇报更出彩!
  5. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十七)地图自适应区域加载...
  6. 搜索——I’m stuck!(ccf)
  7. laravel控制器方法中,用函数作为变量进行传递时的处理方法
  8. IAR执行到断点处不能单步运行解决方法
  9. 四阶行列式计算_四阶行列式的计算
  10. 非常好的Java反射例子
  11. 逻辑斯蒂回归java_机器学习 (五)逻辑斯蒂回归
  12. 酒吧声场测试软件,做到以下几点 酒吧音响效果出奇的好
  13. SQL Server 的完整下载安装教程
  14. Integrity数据库简介
  15. 一入IT深似海,从此都是考证人~耗时,耗力,耗财,耗头发考过的证书 千万不要忘了延续~
  16. 小程序全套购物车(全选,单选,反选,删除,价格计算)
  17. 【翻译论文】An Architecture Combining Convolutional Neural Network (CNN) and Support Vector Machine (SVM)
  18. switch分支语句注意事项及注册界面的使用思路
  19. import绝对路径问题
  20. 开源免费的舆情系统的架构

热门文章

  1. 码农技术炒股之路——数据库管理器、正则表达式管理器
  2. WMI技术介绍和应用——查询时间信息
  3. 一种在注入进程中使用WTL创建无焦点不在任务栏出现“吸附”窗口的方法和思路
  4. 男孩子学计算机和学医哪个好,你认为学医好还是读211大学的电子信息好?
  5. android4.3.0 camera,4.3、高通camera驱动简析
  6. java 正则 cpu 100_这六个原因真的可以使Java应用程序的CPU使用率飙升到100%吗?...
  7. 怎样在表格中选出同一类_超超超超实用的年会策划执行表格模板合集!
  8. Java项目:酒店管理系统(java+Springboot+Mybatis+Beetl+Layui)
  9. mysql客户端指令_mysql command line client(mysql命令行客户端)
  10. 【单片机】写电子钟时遇到的问题