使用Spring Boot开发应用:基于请求参数MD5的缓存键及其他缓存方式

news2024/9/9 4:39:09

本文将介绍如何在Spring Boot应用中实现基于请求参数MD5的缓存键,以及其他常见的缓存方式。通过实际代码示例,展示如何应用这些技术优化系统性能。

1. 引入必要的依赖

首先,在Spring Boot项目中引入缓存相关的依赖。修改pom.xml文件,添加如下依赖:

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <!-- Optional: Spring Boot Starter Data Redis for Redis Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

2. 配置缓存

application.properties中进行缓存配置。这里以内存缓存(如ConcurrentMapCacheManager)为例:

spring.cache.type=simple

如果使用Redis作为缓存,可以进行如下配置:

spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

3. 启用缓存支持

在Spring Boot应用的主类或配置类上添加@EnableCaching注解:

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

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

4. 计算请求参数的MD5作为缓存键

创建一个自定义缓存键生成器,计算请求参数的MD5值并作为缓存键:

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        try {
            // 将请求参数按一定顺序组合成字符串
            String paramStr = Arrays.stream(params)
                    .map(Object::toString)
                    .reduce((a, b) -> a + "&" + b)
                    .orElse("");

            // 计算MD5值
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(paramStr.getBytes(StandardCharsets.UTF_8));

            // 转换为32位的哈希值
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

5. 应用缓存注解

在服务层应用缓存注解,使用自定义的缓存键生成器:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Cacheable(value = "myCache", keyGenerator = "customKeyGenerator")
    public String getData(String param1, String param2) {
        // 模拟耗时操作
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Data from " + param1 + " and " + param2;
    }
}

6. 其他缓存方式

除了使用请求参数的MD5作为缓存键外,还可以采用其他缓存方式,如直接使用请求参数、组合多个参数等。示例如下:

6.1 直接使用请求参数作为缓存键


@Cacheable(value = "myCache", key = "#param1 + '-' + #param2")
public String getDataUsingParams(String param1, String param2) {
    // 模拟耗时操作
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Data from " + param1 + " and " + param2;
}

6.2 组合多个参数作为缓存键

@Cacheable(value = "myCache", key = "T(String).valueOf(#param1).concat('-').concat(T(String).valueOf(#param2))")
public String getDataUsingCombinedParams(String param1, String param2) {
    // 模拟耗时操作
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Data from " + param1 + " and " + param2;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python报错已解决】`AttributeError: ‘DataFrame‘ object has no attribute ‘ix‘`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引言&#xff1a; 在数据分析或者数据处理的过程中&#xff0c;我们经常会遇到各种各样的报错信息&#xff0c;这些报错信息往…

【漏洞复现】APP分发签名系统index-uplog.php存在任意文件上传漏洞

漏洞描述 APP分发签名系统index-uplog.php存在任意文件上传漏洞 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵…

游戏类App出海广告变现,新手开发者如何选对聚合广告平台?

无论是轻量化小游戏还是中重度游戏&#xff0c;厂商的终极目标都是盈利。从商业化角度来说&#xff0c;单一的变现模式存在一些问题。纯内购驱动的游戏除了少数大竞技品类&#xff0c;大多是为垂直玩家设计&#xff0c;难以扩量。而纯广告变现驱动的游戏&#xff0c;在抗风险方…

所谓有趣的灵魂,实际上就是这个人的信息密度和知识层面,都远高于你!

1. 信息界的“百科全书” 信息密度&#xff1a;大脑里的“硬盘” 我们先来八一八什么是信息密度。想象一下&#xff0c;如果大脑是个硬盘&#xff0c;那么信息密度高的人&#xff0c;硬盘里存的可都是高清大片和无损音乐&#xff0c;随时准备给你来一场视听盛宴。 知识层面&am…

vue3数据结构的渲染01

处理数据&#xff1a; //现有原始数据showCertificateUrl “url01;url02” 使用以下代码将两条通过分号";"分割的url进行处理 const parseUrls () > {urls.value [];// 每次重新赋值前一定要清空之前的旧数据&#xff01;if (!showCertificateUrl.value) {retu…

[前端]解决Iframe即使设置高度100%,但还是显示滚动条scrollbar的问题

前言 好烦,你看看这两个重复的滚动条. 一个是来自iframe,另一个来自父级的div(overflow: auto;) 我已经在css中设置了iframe的height: 100%;border: none;,但无论如何还是显示出了父级的scrollbar 解决 将iframe的display: block;即可. 或者vertical-align: bottom;

安全测试与渗透测试的区别

在这个数字化时代&#xff0c;网络安全如同数字世界的守护神&#xff0c;其重要性不言而喻。而在这场没有硝烟的战争中&#xff0c;安全测试与渗透测试作为两大核心利器&#xff0c;常常被提及却又容易混淆。今天&#xff0c;就让我们揭开它们的神秘面纱&#xff0c;一探二者之…

2024.7.30 作业

1> 使用文件IO完成&#xff0c;将源文件中的所有内容进行加密&#xff08;大写转小写、小写转大写&#xff09;后写入目标文件中&#xff0c;源文件内容不变 #include <myhead.h> int main(int argc,const char *argv[]) {int fd1 -1,fd2 -1;if((fd1 open(".…

【和相同的二元子数组】python刷题记录

R2-前缀和专题 目录 前缀和哈希表 双指针 ps: 第一眼过去&#xff0c;这题应该能用双指针解出来&#xff0c;应该也能用前缀和解题。 前缀和哈希表 适用于 nums[i] 值不固定为 0 和 1 的其他情况 class Solution:def numSubarraysWithSum(self, nums: List[int], goal: i…

Vue入门记录(一)

效果 本文为实现如下前端效果的学习实践记录&#xff1a; 实践 入门的最佳实践我觉得是先去看官网&#xff0c;官网一般都会有快速入门指引。 根据官网的快速上手文档&#xff0c;构建一个新的Vue3TypeScript&#xff0c;查看新建的项目结构&#xff1a; 现在先重点关注comp…

前端科举八股文-手撕代码篇

前端科举八股文-手撕代码篇 手撕排序算法选择排序思路 冒泡排序思路 快速排序思路 手撕bind方法思路解析 手撕js的继承方案构造继承实现原理 原型继承实现原理 组合继承实现原理 寄生组合继承实现原理 手撕instanceOf实现原理 手撕new 操作符手撕防抖实现原理 手撕节流实现原理…

Java8 新特性,看这篇文章就够了

Java8 是 Java 编程语言的一个重要版本&#xff0c;于 2014 年 3 月发布。它引入了许多新的功能和改进&#xff0c;其中包括 Lambda 表达式、Stream API、新的日期/时间 API 和 Nashorn JavaScript 引擎等。 Java 8 的主要特点如下&#xff1a; Lambda 表达式&#xff1a;Lamb…

Linux进程--exec族函数

exec族函数函数的作用&#xff1a; 我们用fork函数创建新进程后&#xff0c;经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时&#xff0c;该进程被完全替换为新程序。因为调用exec函数并不创建新进程&#xff0c;所以前后进程的ID并没有改变。 原文链…

电测量数据交换DLMSCOSEM组件第53部分:DLMSCOSEM应用层(下)

3.DLMS/COSEM应用层协议规范 3.1控制功能 3.1.1客户机侧功能的状态定义 图37显示了客户机侧CF的状态机。 客户机CF(和AL包含CF)的状态定义如下: ——INACTIVE:在该状态下,CF完全没有活动;它既不给AP提供服务,也不使用协议支撑层服务; ——IDLE:在没有AA存在…

SpringBoot(看这一篇就够了)

目录&#xff1a; SpringBootSpring的缺点什么是SpringBoot&#xff1f;Springboot3 版本要求Springboot的三种构建方式官网搭建通过IDEA脚手架搭建通过Maven搭建项目 SpringBoot的项目结构编写一个测试代码YAML文件自定义配置文件Value读取配置文件ConfigurationProperties读取…

阿里P8大佬推荐的前端书籍资料,限时免费领取!

&#x1f381; 限时福利大放送&#xff01; &#x1f389; 亲爱的前端小伙伴们&#xff0c;今天给大家分享几个前端必备资料 有P8大佬的算法解题笔记, 最新大厂高频100题, 前端经典八股文&#xff0c;也有一些前端经典书籍&#xff0c;如nodejs&#xff0c;http&#xff0c;jav…

ros笔记04--从零体验ros2行为通信方式

ros笔记04--从零体验ros2行为通信方式 介绍创建步骤体验官方案例基于python开发行为案例创建action接口创建action sever和client 注意事项说明 介绍 行为是ros2中的一种通信方式&#xff0c;其多被用于一些长时间运行的任务&#xff0c;它包含了目标、反馈、结果三部分。 行为…

科普文:从源码解读5种Redis基本数据类型

键值对字符串 char* 与 SDS char* 的不足&#xff1a; 操作效率低&#xff1a;获取长度需遍历&#xff0c;O(N)复杂度 二进制不安全&#xff1a;无法存储包含 \0 的数据 SDS 的优势&#xff1a; 操作效率高&#xff1a;获取长度无需遍历&#xff0c;O(1)复杂度&#xff08…

HIS系统搭建|HIS系统功能|HIS系统开发

在当今医疗信息化的浪潮中&#xff0c;医院信息系统&#xff08;HIS&#xff09;的搭建成为了提升医疗服务效率和质量的关键。HIS系统不仅仅是一个简单的数据记录工具&#xff0c;它是一个集成了预约挂号、病历管理、药品管理、财务结算等多个功能模块的综合性平台。通过这一系…

使用idea集成的springboot实现注册接口

跟黑马程序员学pringboot3vue3,代码都是黑马程序员视频里的代码 实战篇-03_注册接口_哔哩哔哩_bilibili 本文仅仅用于学习记录 开发用户接口 注册接口 开发流程&#xff1a;明确需求>>阅读接口文档>>思路分析>>开发>>测试 分析&#xff1a; 这个…