首页 > 其他分享 >使用 SpringCache 简化缓存代码实现

使用 SpringCache 简化缓存代码实现

时间:2023-04-30 20:55:52浏览次数:45  
标签:缓存 SpringCache name cache springframework 简化 org import

SpriingCache 实现了基于注解的缓存功能,只需要在方法上添加注解即可实现常用的缓存功能,大大简化了的业务代码的实现。SpringCache 默认集成于 SpringContext 中,这意味着对于使用 SpringBoot 框架来说,不需要引入额外的 jar 包即可使用。

SpringCache 通过 CacheManager 接口来统一不同的缓存技术,底层可以切换不同的 cache 实现。默认采用 ConcurrentMapCacheManager 实现缓存功能。如果想使用 Redis 作为缓存,只需要在 Springboot 程序中引入 Redis 的起步依赖即可自动切换到 RedisCacheManager。

下面就让我们体验一下 SpringCache 的具体功能吧,在博客的最后会提供源代码下载。


一、搭建工程

搭建一个 SpringBoot 程序,结构如下所示:

image

pom 文件的具体内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.10</version>
    </parent>

    <groupId>com.jobs</groupId>
    <artifactId>spring_cache_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

可以发现除了 web 实现必须要引用的 spring-boot-starter-web 起步依赖和 lombok 之外,没有引入额外的 jar 包。其中 lombok 不是必须要引入的,之所以引入是为了简化实体对象的创建,以及使用其 lombok 自带的日志打印功能。

本博客的 Demo 使用的实体类 Employee 细节如下:

package com.jobs.entity;

import lombok.Data;
import java.io.Serializable;

//每个实体类,最好实现 Serializable 接口,否则可能会出错
@Data
public class Employee implements Serializable {

    private String name;

    private int age;
}

这里需要注意的是:所有实体类最好实现 Serializable 接口,比如对于大部分的 CacheManager 的实现是基于 jdk 的序列化,要求实体类必须实现 Serializable 接口,否则在使用 SpringCache 的过程中就会报错。

对于 application.yml 配置文件,内容很简单,只配置了启动端口,如下所示:

server:
  port: 8888

二、使用默认的缓存功能

SpringCache 是基于注解的缓存实现,常用的注解有:

  • @EnableCaching 这个注解需要在 SpringBoot 启动类上添加后,才能使用 SpringCache 的其它注解
  • @Cacheable 在方法执行前先查看是否有相应缓存,有则直接返回缓存,无则调用方法并将方法返回值放到缓存中
  • @CachePut 方法执行完毕后,将结果添加到缓存中
  • @CacheEvict 删除一条或所有缓存

首先我们需要在 SpringBoot 的启动类上,添加 @EnableCaching 注解。

package com.jobs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

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

然后在 EmployeeController 中编写用于测试的接口,具体细节如下:

package com.jobs.controller;

import com.jobs.entity.Employee;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.Random;

@Slf4j
@RequestMapping("/employee")
@RestController
public class EmployeeController {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private CacheManager cacheManager;

    //当接收到的参数封装的实体不为 null 时,添加缓存。(condition 表示满足条件时,对执行结果进行缓存)
    // key 不存在时,添加缓存,如果 key 存在时,则更新缓存
    // #emp.name 表示使用接收到的实体对象的 name 作为 key
    // #result.name 表示使用返回的结果对象的 name 作为 key
    //@CachePut(value = "employee", key = "#emp.name", condition = "#emp != null")
    @CachePut(value = "employee", key = "#result.name", condition = "#emp != null")
    @PostMapping
    public Employee addEmployee(@RequestBody Employee emp) {
        log.info("addEmployee 传入的参数:" + emp);
        if (emp != null) {
            return emp;
        } else {
            return null;
        }
    }

    //使用接收到的参数 name 作为 key
    //当返回结果不是 null 时,进行缓存。(unless 表示不满足条件时,对执行结果进行缓存)。
    //当 key 存在时,直接返回缓存中的数据
    @Cacheable(value = "employee", key = "#name", unless = "#result == null")
    @GetMapping("/{name}")
    public Employee getEmployee(@PathVariable String name) {
        log.info("getEmployee 传入的参数:" + name);
        if (name == null || name.length() == 0) {
            return null;
        } else {
            Employee emp = new Employee();
            emp.setName(name);
            emp.setAge(new Random().nextInt(100));
            return emp;
        }
    }

    //删除缓存,使用接收到的参数 name 作为 key 进行删除
    @CacheEvict(value = "employee", key = "#name")
    @DeleteMapping
    public void deleteEmployee(String name) {
        log.info("deleteEmployee 传入的参数:" + name);
    }

    //查看缓存(对于 Redis 来说,该方法不可用,
    //因为基于 redis 的 Cache 具体实现类,没有实现 Serializable 接口)
    @GetMapping("/cache")
    public Cache viewCache(String key) {
        Cache cache = cacheManager.getCache("employee");
        if (cache != null) {
            return cache;
        } else {
            return null;
        }
    }
}

这里需要注意的是:@Cacheable 、@CachePut、@CacheEvict 这些注解的 value 值表示的是缓存的类别。

然后启动 SpringBoot 程序,使用 Postman 工具模拟 http 请求接口来测试,想要查看缓存,可以请求 localhost:8888/employee/cache 接口进行验证,由于 SpringCache 默认使用 ConcurrentMapCacheManager 在内存中保存缓存数据,因此重启 SpringBoot 程序后,缓存就消失了。


三、使用 Redis 缓存

上面的代码不需要进行任何更改,只需要引入 Redis 的起步依赖,然后在 application.yml 增加 Redis 的配置即可。

1 在 pom 文件中添加 Redis 的起步依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2 在 application.yml 中添加 Redis 的配置

spring:
  redis:
    host: 192.168.216.128
    port: 6379
    # redis 的连接密码,如果没有密码,可以省略
    password: redis123
    # redis 默认 16 个库,可选编号为 0 到 15,默认就是 0
    database: 0
  cache:
    redis:
      # 缓存有效期,单位是毫秒,此处设置 30 分钟
      time-to-live: 1800000

然后继续使用 Postman 工具进行接口测试,此时直接在 Redis 中查看结果进行验证。


本篇博客的源代码下载地址:https://files.cnblogs.com/files/blogs/699532/spring_cache_demo.zip

标签:缓存,SpringCache,name,cache,springframework,简化,org,import
From: https://www.cnblogs.com/studyjobs/p/17365750.html

相关文章

  • Hibernate缓存机制
      Hibernate缓存分类:Hibernate的缓存范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作......
  • Django笔记三十三之缓存操作
    本文首发于公众号:Hunter后端原文链接:Django笔记三十三之缓存操作这一节介绍一下如何在Django中使用redis做缓存操作。在Django中可以有很多种方式做缓存,比如数据库,比如服务器文件,或者内存,这里介绍用的比较多的使用redis作为缓存。这篇笔记主要内容如下:依赖安装se......
  • rfc7234之http缓存
    声明:本人原创文章,详细内容已发布在我的微信个人技术公众号---网络技术修炼,公众号总结普及网络基础知识,包括基础原理、网络方案、开发经验和问题定位案例等,欢迎关注。缓存概念缓存处理请求步骤缓存如果查询到某个请求已经有缓存,那么需要进一步检查该资源的新鲜度,根据新鲜度和......
  • redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化
    目录redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化昨日内容回顾今日内容详细1持久化方案1.1RDB1.2aof方案1.3混合持久化2主从复制原理和方案3哨兵高可用4集群原理及搭建4.1集群搭建4.2集群扩容4.3集群缩容5缓存优化5.1redis缓存更新策略5.2缓存穿透击......
  • CefSharp自定义缓存实现
    大家好,我是沙漠尽头的狼。上文介绍了《C#使用CefSharp内嵌网页-并给出C#与JS的交互示例》,本文介绍CefSharp的缓存实现,先来说说添加缓存的好处:提高页面加载加速:CefSharp缓存可以缓存已经加载过的页面和资源,当用户再次访问相同的页面时,可以直接从缓存中加载,而不需要重新下载和解......
  • CefSharp自定义缓存实现
    大家好,我是沙漠尽头的狼。上文介绍了《C#使用CefSharp内嵌网页-并给出C#与JS的交互示例》,本文介绍CefSharp的缓存实现,先来说说添加缓存的好处:提高页面加载加速:CefSharp缓存可以缓存已经加载过的页面和资源,当用户再次访问相同的页面时,可以直接从缓存中加载,而不需要重新下载和解......
  • redis,python操作哨兵,python操作集群,缓存优化,缓存击穿,穿透,雪崩
    python操作哨兵高可用架构后》不能直接连接某一个主库》主库可能会挂掉,后来他就不是主库了之前的连接redis操作就不能用了importredisconn=redis.Redis(host='',port=6379)conn.set()conn.close()新的连接哨兵的操作连接哨兵服务器(主机名也可以用做域名)配置文件#redi......
  • pytest之.pytest_cache文件夹作用【Pytest中的cache缓存功能】
     前言pytest运行完用例之后会生成一个.pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。1、跑自动化时经常会出现这样一个情况,一轮自动化跑完后零星出现了几个失败测试用例,无法断定失败的原因,所以可能需要重新跑一下失败的测试用例去调试,那我们要做的是就去......
  • 真的只是简单了解下浏览器缓存
    01、什么是HTTP缓存,如何工作的?当我们打开一个页面时,会向服务端发起很多次请求,如下图打开百毒首页,发起了HTML、各种图片、JS、CSS等资源共72次请求。这里面很多资源并不会频繁变化,每次打开页面都重新请求下载,就很浪费了。浏览器缓存也称为HTTP缓存,HTTP缓存简单理解就是本地(浏览......
  • Solr之缓存篇
    Solr在Lucene之上开发了很多Cache功能,从目前提供的Cache类型有:(1)filterCache(2)documentCache(3)fieldvalueCache(4)queryresultCache而每种Cache针对具体的查询请求进行对应的Cache。本文将从几个方面来阐述上述几种Cache在Solr的运用,具体如下:(1)Cache的生命周期(2)Cache的使用场景(3)C......