计算机领域有人说过一句名言:“计算机科学领域的任何问题都可以通过增加一个中间层来解决”,今天我们就用Spring-cache给网站添加一层缓存,让你的网站速度飞起来。

本文目录

一、Spring Cache介绍二、缓存注解介绍三、Spring Boot+Cache实战1、pom.xml引入jar包2、启动类添加@EnableCaching注解3、配置数据库和redis连接4、配置CacheManager5、使用缓存注解6、查看缓存效果7、注意事项

一、Spring Cache介绍

Spring 3.1引入了基于注解的缓存(cache)技术,它本质上是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种注解,就能够达到缓存方法的效果。

Spring Cache接口为缓存的组件规范定义,包含缓存的各种操作集合,并提供了各种xxxCache的实现,如RedisCache,EhCacheCache,ConcurrentMapCache等;

项目整合Spring Cache后每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过,如果有就直接从缓存中获取结果,没有就调用方法并把结果放到缓存。

二、缓存注解介绍

对于缓存声明,Spring的缓存提供了一组java注解:

  • @CacheConfig:设置类级别上共享的一些常见缓存设置。
  • @Cacheable:触发缓存写入。
  • @CacheEvict:触发缓存清除。
  • @Caching 将多种缓存操作分组
  • @CachePut:更新缓存(不会影响到方法的运行)。

@CacheConfig
该注解是可以将缓存分类,它是类级别的注解方式。我们可以这么使用它。
这样的话,UserServiceImpl的所有缓存注解例如@Cacheable的value值就都为user。

@CacheConfig(cacheNames = "user")
@Service
public class UserServiceImpl implements UserService {}

@Cacheable
一般用于查询操作,根据key查询缓存.

  1. 如果key不存在,查询db,并将结果更新到缓存中。
  2. 如果key存在,直接查询缓存中的数据。
    //查询数据库后 数据添加到缓存
    @Override
    @Cacheable(cacheNames = "cacheManager", key = "'USER:'+#id", unless = "#result == null")
    public User getUser(Integer id) {
        return repository.getUser(id);
    }

@CachePut
@CachePut标注的方法在执行前不会去检查缓存中是否存在,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

    //修改数据后更新缓存
    @Override
    @CachePut(cacheNames = "cacheManager", key = "'USER:'+#updateUser.id", unless = "#result == null")
    public User updateUser(User updateUser) {
        return repository.save(updateUser);
    }

@CacheEvict
根据key删除缓存中的数据。allEntries=true表示删除缓存中的所有数据。

    //清除一条缓存,key为要清空的数据
    @Override
    @CacheEvict(cacheNames = "cacheManager", key = "'USER:'+#id")
    public void deleteUser(Integer id) {
        repository.deleteById(id);
    }

三、Spring Boot+Cache实战

1、pom.xml引入jar包

<!-- 引入缓存 starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 引入 redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、启动类添加@EnableCaching注解

@EnableCaching注解是spring framework中的注解驱动的缓存管理功能,当你在配置类(@Configuration)上使用@EnableCaching注解时,会触发一个post processor,这会扫描每一个spring bean,查看是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。

启动类部分代码如下:

@SpringBootApplication
@EnableCaching
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

3、配置数据库和redis连接

application.properties部分配置如下:

#配置数据源信息
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.1.1:3306/test
spring.datasource.username=root
spring.datasource.password=1234
#配置jpa
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
# Redis服务器地址
spring.redis.host=192.168.1.1
# database
spring.redis.database = 1
# Redis服务器连接端口 使用默认端口6379可以省略配置
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=1234
# 连接池最大连接数(如果配置<=0,则没有限制 )
spring.redis.jedis.pool.max-active=8

4、配置CacheManager

WebConfig.java部分配置如下:

@Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //缓存配置对象
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();         redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) //设置缓存的默认超时时间:30分钟
                .disableCachingNullValues()             //如果是空值,不缓存
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))         //设置key序列化器
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer((valueSerializer())));  //设置value序列化器         return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

5、使用缓存注解

UserServiceImpl.java中使用缓存注解示例如下:

//查询数据库后 数据添加到缓存
    @Override
    @Cacheable(cacheNames = "cacheManager", key = "'USER:'+#id", unless = "#result == null")
    public User getUser(Integer id) {
        return repository.getUser(id);
    }     //清除一条缓存,key为要清空的数据
    @Override
    @CacheEvict(cacheNames = "cacheManager", key = "'USER:'+#id")
    public void deleteUser(Integer id) {
        repository.deleteById(id);
    }     //修改数据后更新缓存
    @Override
    @CachePut(cacheNames = "cacheManager", key = "'USER:'+#updateUser.id", unless = "#result == null")
    public User updateUser(User updateUser) {
        return repository.save(updateUser);
    }

6、查看缓存效果

启动服务后,访问两次http://localhost:8090/getUser/2接口,从打印日志可以看到,第一次请求打印了sql说明查询了数据库,耗时960,而第二次直接查询的缓存耗时66,增加缓存后速度提升非常明显。


postman访问截图


日志截图

7、注意事项

Spring cache是基于Spring Aop来动态代理机制来对方法的调用进行切面,这里关键点是对象的引用问题,如果对象的方法是内部调用(即 this 引用)而不是外部引用,则会导致 proxy 失效,那么我们的切面就失效,也就是说上面定义的各种注释包括 @Cacheable、@CachePut 和 @CacheEvict 都会失效。

到此Spring Boot 2.X中整合Spring-cache与Redis功能全部实现,有问题欢迎留言沟通哦!
完整源码地址: https://github.com/suisui2019/springboot-study

推荐阅读

1.Spring Boot 2.X 整合Redis
2.Spring Boot 2.X 如何优雅的解决跨域问题?
3.Spring Boot 2.X 集成spring session实现session共享
4.Spring条件注解@Conditional
5.SpringBoot 2.X从0到1实现邮件发送功能
6.Redis批量删除key的小技巧,你知道吗?
7.Spring Boot 2.X 如何快速整合jpa?
8.Spring Boot之Profile--快速搞定多环境使用与切换
9.Spring Boot快速集成kaptcha生成验证码


限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。
关注下方公众号即可免费领取:

Java碎碎念公众号

Spring Boot 2.X整合Spring-cache,让你的网站速度飞起来的更多相关文章

  1. Spring Boot 2.x整合Redis

    最近在学习Spring Boot 2.x整合Redis,在这里和大家分享一下,希望对大家有帮助. Redis是什么 Redis 是开源免费高性能的key-value数据库.有以下的优势(源于Redis ...

  2. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  3. Spring Boot 2.0 整合携程Apollo配置中心

    原文:https://www.jianshu.com/p/23d695af7e80 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够 ...

  4. spring boot 2.0 整合 elasticsearch6.5.3,spring boot 2.0 整合 elasticsearch NoNodeAvailableException

    原文地址:spring boot 2.0 整合 elasticsearch NoNodeAvailableException 原文说的有点问题,下面贴出我的配置: 原码云项目地址:https://gi ...

  5. Spring Boot入门 and Spring Boot与ActiveMQ整合

    1.Spring Boot入门 1.1什么是Spring Boot Spring 诞生时是 Java 企业版(Java Enterprise Edition,JEE,也称 J2EE)的轻量级代替品.无 ...

  6. Spring Boot和Dubbo整合

    provider端 POM依赖 <dependencies> <dependency> <groupId>org.springframework.boot</ ...

  7. 转-Hive/Phoenix + Druid + JdbcTemplate 在 Spring Boot 下的整合

    Hive/Phoenix + Druid + JdbcTemplate 在 Spring Boot 下的整合 http://blog.csdn.net/balabalayi/article/detai ...

  8. RabbitMQ入门:在Spring Boot 应用中整合RabbitMQ

    在上一篇随笔中我们认识并安装了RabbitMQ,接下来我们来看下怎么在Spring Boot 应用中整合RabbitMQ. 先给出最终目录结构: 搭建步骤如下: 新建maven工程amqp 修改pom ...

  9. Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档

    0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...

随机推荐

  1. 第04组 Beta冲刺(2/4)

    队名:斗地组 组长博客:地址 作业博客:Beta冲刺(2/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.分配展示任务 2.收集各个组员的进度 3.写博客 展示GitHub当日代码/文档 ...

  2. java之this关键字和super关键字的区别

    编号 区别点 this super 1 访问属性 访问本类中的属性,如果本类没有此 属性则从父类中继续查找 访问父类中的属性 2 调用方法 访问本类中的方法 直接访问父类中的方法 3 调用构造器 调用 ...

  3. C语言程序设计100例之(15):除法算式

    例15   除法算式 问题描述 输入正整数n(2≤n≤68),按从小到大输出所有形如abcde/fghi=n的表达式.其中a~i为1~9的一个排列. 输入格式 每行为一个正整数n (n <= 1 ...

  4. Vue 小练习01

    有红, 黄, 蓝三个按钮, 以及一个200X200px的矩形box, 点击不同的按钮, box的颜色会被切换为指定的颜色 <!DOCTYPE html> <html lang=&qu ...

  5. php中文乱码原因和维修方法

    一.首先是PHP网页的编码 1.如果欲使用gb2312编码,那么php要输出头:header(“Content-Type: text/html; charset=gb2312”),静态页面添加,所有文 ...

  6. pip安装插件报错。

    报错: Cannot unpack file C:\Windows\TEMP\pip-unpack-4mbfczpj\simple (downloaded from C:\Windows\TEMP\p ...

  7. 【ST开发板评测】Nucleo-F411RE开箱报告

    前言 面包板又举办开发板试用活动了,很荣幸能获得一块ST官方的Nucleo-F411RE开发板,感谢面包板社区和ST意法半导体的赞助,这是我第一次试用官方的开发板,收到板子后查了一些关于ST官方开发板 ...

  8. javascript数组在指定位置添加和删除元素

    在JavaScript中,Array对象提供了一个强大的splice()方法,利用这个方法可以达到在数组的指定位置添加和删除元素的目的. 指定位置删除元素 要在指定位置删除元素,可以使用splice( ...

  9. python是什么?python能做什么?

    人生苦短,我用python. python是什么? Python是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. python语言有以下特点: 易于学习.Python有相对较少的关键字 ...

  10. golang-基础

    1.go的特点 兼具动态语言的开发效率与C,C++,java的性能安全性 ,内置编译器 2.go的安装 go的sdk下载:  https://studygolang.com/dl go的IDE下载: ...