案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序

案例

@Cacheable 是 Spring Framework 提供的一个注解,用于在方法执行前先检查缓存,如果缓存中已存在对应的值,则直接返回缓存中的值,而不执行该方法体。如果缓存中不存在对应的值,则执行方法体,并将方法的返回值存入缓存供下次使用。

在 Spring Boot 中,@Cacheable 注解通常与缓存管理器一起使用,可以轻松地在方法级别上实现缓存功能,避免不必要的重复计算或查询数据库操作,从而提高应用程序的性能和响应速度。

如何使用 @Cacheable 注解:

  1. 配置缓存管理器:首先,需要在 Spring Boot 应用中配置一个缓存管理器,例如使用 EhCache、Caffeine、Redis 等。这通常可以通过添加相应的依赖和配置来实现。

  2. 在方法上添加 @Cacheable 注解:将 @Cacheable 注解添加到需要缓存的方法上,并指定缓存的名称或缓存管理器的名称,以及缓存的 key。

这种方式能够显著提高应用程序的性能,特别是在需要频繁访问相同数据的场景下,通过缓存可以避免重复的耗时操作。

案例-生成验证码

这里有一个词语

Caffenine 要记住

当前默认的缓存方案是Simple

缓存的使用案例——手机验证码

首先我们要封装实体类

在domain包下创建类SMSCode

用lombok进行封装

package com.example.demo.domain;

import lombok.Data;

@Data
public class SMSCode {
    private String tele;
    private String code;
}

在做一个业务层接口

放在service包下

有两个方法

第一个方法是生成验证码

第二个方法是一个校验作用

package com.example.demo.service;

import com.example.demo.domain.SMSCode;
import org.apache.ibatis.annotations.Mapper;


public interface SMSCodeService {
    public String sendCodeToSMS(String tele);
    public boolean checkCode(SMSCode smsCode);
}

做业务层的实现类

即为刚刚的接口书写实现类

package com.example.demo.service.impl;

import com.example.demo.domain.SMSCode;
import com.example.demo.service.SMSCodeService;
import org.springframework.stereotype.Service;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Override
    public String sendCodeToSMS(String tele) {
        return null;
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        return false;
    }
}

接下来书写表现层代码

Controller

package com.example.demo.controller;

import com.example.demo.domain.SMSCode;
import com.example.demo.service.SMSCodeService;
import jdk.nashorn.internal.runtime.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService smsCodeService;

    @GetMapping
    public String getCode(String tele){
        String code =smsCodeService.sendCodeToSMS(tele);
        return code;
    }

    @PostMapping
    public boolean checkCode(SMSCode smsCode){
        return  smsCodeService.checkCode(smsCode);
    }

}

接下来就是最核心的内容了

我们要在业务层去完善代码

我们是不是需要一个验证码

我们去创建一个工具类

去校验对应的验证码

创建一个工具类

注意的是

生成验证码的时候

要进行补全

package com.example.demo.utils;

import org.springframework.stereotype.Component;

@Component
public class CodeUtils {
    public String generator(String tele){
        int hash=tele.hashCode();
        int encryption=20206666;
        long result=hash^encryption;
        long nowTime=System.currentTimeMillis();
        result=result^nowTime;
        long code=result%1000000;
        code=code<0?-code:code;
        return String.format("%06d",code);
    }

//    //启动注释
//    public static void main(String[] args) {
//        while(true)
//            System.out.println(new CodeUtils().generator("19850593532"));
//    }

}

当然我们也可以拼接

把0 00 000 0000 00000放到一个数组里面去

然后判断生成验证码的长度 然后直接进行拼接

接下来我们要去补全业务层的实现类

我们把缓存注入 挂到实现类上面去

接下来我们要去检查缓存的依赖是否引入boot工程

看看启动响应类里面有没有打开缓存功能

检查完毕

我们直接给业务层实现类挂一个缓存就行

@Override
@Cacheable(value = "smsCode",key="#tele")
public String sendCodeToSMS(String tele) {
    String code=codeUtils.generator(tele);
    return code;
}

启动我们的boot工程

我们打开postman

向服务器发起请求

依靠我们之前在表现层书写的get请求

@GetMapping
public String getCode(String tele){
    String code =smsCodeService.sendCodeToSMS(tele);
    return code;
}

获取到了验证码

但是这边有个小问题

我们用同一个手机号发验证码

发起请求无论有多少次

获取到的验证码都是一样的

说明有缓存了

所以我们就思考到了

为什么我们每次靠手机号发送验验证码的时候会进入60秒的冷却等待时间

换个注解

仅仅往里面放缓存

    @Override
//    @Cacheable(value = "smsCode",key="#tele")
    @CachePut(value = "smsCode",key="#tele")
    public String sendCodeToSMS(String tele) {
        String code=codeUtils.generator(tele);
        return code;
    }

这样就能获取到了

手机验证码 每次这个数值 都会变化

案例-校验功能

可以去CSDN学习下<artifactId>qcloudsms</artifactId>这个依赖

用到项目中,可以直接给手机发验证码(腾讯云SMS)

但是我们这边会有一个小问题

运行get的时候才会进行缓存

先执行代码在执行注解

注解根本就没有运行

注解没运行 返回null

注解根本就没加载

并没有执行spring容器管理

我们每次执行的时候都是空指针 返回值都是空

作为ioc容器管理的对象,其中注解生效。但如果不使用对象直接调用当然不生效

加了缓存的注解就相当于会给当前类生成一个代理对象, aop的思想, 在controller里调用方法和用this调用方法一个是走代理一个不走代理

同一个类中调用,没有使用ioc容器中的对象调用方法,注解没有被扫描,使用ioc容器的方法,注解才会被扫描

方法调用同实列的方法,代理失效

@Service也是个bean,但是写在service下用this调用,只是走普通方法的调用,没经过spring容器,@Cacheable也就没启动,所以取不到缓存的值,我是这样理解的

我想明白了,上面那个CachePut能使用是因为这个方法是在controller里面被调用的,用bean调用的,而这个是在service里面的方法间调用的,一个普通的类间的方法互相调用

我们的业务层核心逻辑

package com.example.demo.service.impl;

import com.example.demo.domain.SMSCode;
import com.example.demo.service.SMSCodeService;
import com.example.demo.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {

    @Autowired
    private CodeUtils codeUtils;

    @Override
//    @Cacheable(value = "smsCode",key="#tele")
    @CachePut(value = "smsCode",key="#tele")
    public String sendCodeToSMS(String tele) {
        String code=codeUtils.generator(tele);
        return code;
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        String code=smsCode.getCode();
        String cacheCode=codeUtils.get(smsCode.getTele());
        return code.equals(cacheCode);
    }

}

解决方案

我们要把get方法放到工具类里面去

package com.example.demo.utils;

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

@Component
public class CodeUtils {
    public String generator(String tele){
        int hash=tele.hashCode();
        int encryption=20206666;
        long result=hash^encryption;
        long nowTime=System.currentTimeMillis();
        result=result^nowTime;
        long code=result%1000000;
        code=code<0?-code:code;
        return String.format("%06d",code);
    }
    @Cacheable(value = "smsCode",key="#tele")
    public String get(String tele){
        return null;
    }
}

这样我们就能用bean去调用

这个方法

就能让cacheCode

很巧合的加载进来

我们用postman获取

这样就代表我们的案例书写成功

个人号推广

博客主页

多多!-CSDN博客

Web后端开发

https://blog.csdn.net/qq_30500575/category_12624592.html?spm=1001.2014.3001.5482

Web前端开发

https://blog.csdn.net/qq_30500575/category_12642989.html?spm=1001.2014.3001.5482

数据库开发

https://blog.csdn.net/qq_30500575/category_12651993.html?spm=1001.2014.3001.5482

项目实战

https://blog.csdn.net/qq_30500575/category_12699801.html?spm=1001.2014.3001.5482

算法与数据结构

https://blog.csdn.net/qq_30500575/category_12630954.html?spm=1001.2014.3001.5482

计算机基础

https://blog.csdn.net/qq_30500575/category_12701605.html?spm=1001.2014.3001.5482

回忆录

https://blog.csdn.net/qq_30500575/category_12620276.html?spm=1001.2014.3001.5482

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

hugo 博客写作流程 (二)

写作工具 推荐两款软件,本人都使用过: typora和obsidian typora: https://github.com/woniu336/typora-007 新建文章 在博客目录找到shell/quickstart.sh双击打开即可 发布到Github 前提: 魔法上网在Github新建一个仓库 找到shell/quickstart.sh双击打开,选择7.SSH 管理…

Android采用Scroller实现底部二楼效果

需求 在移动应用开发中&#xff0c;有时我们希望实现一种特殊的布局效果&#xff0c;即“底部二楼”效果。这个效果类似于在列表底部拖动时出现额外的内容区域&#xff0c;用户可以继续向上拖动查看更多内容。这种效果可以用于展示广告、推荐内容或其他信息。 效果 实现后的…

代理设计模式,框架AOP思想

文章目录 引言&#x1f92a;代理对象(Proxy)如何开发一个代理对象开发中的业务层代码冗余问题开发静态代理类动态代理 引言&#x1f92a; 代理 (proxy) &#xff0c;举个生活中常见的现象&#xff0c;在之前网路还未走进大众的时代里&#xff0c;如果我们想买一些东西&#xf…

Java——构造器(构造方法)和 this

一、什么是构造器 构造器&#xff08;Constructor&#xff09;是Java类的一种特殊方法&#xff0c;用于初始化对象的状态。构造器在创建对象时被调用&#xff0c;可以对对象的成员变量进行初始化。 我之前的文章《Java——类和对象-CSDN博客》中也提到了构造器。 二、构造器…

pc repair

pc repair 修理电脑&#xff0c;换配件

【猫狗分类】Pytorch VGG16 实现猫狗分类1-数据清洗+制作标签文件

Pytorch 猫狗分类 用Pytorch框架&#xff0c;实现分类问题&#xff0c;好像是学习了一些基础知识后的一个小项目阶段&#xff0c;通过这个分类问题&#xff0c;可以知道整个pytorch的工作流程是什么&#xff0c;会了一个分类&#xff0c;那就可以解决其他的分类问题&#xff0…

马斯克在2024年特斯拉股东大会上的年度发言

马斯克表示&#xff0c;“如果市盈率是20或25倍&#xff0c;那就意味着&#xff0c;光是Optimus就能带来20万亿美元的市值。而自动驾驶汽车的市值可能在5到10万亿美元之间。因此&#xff0c;特斯拉的市值达到当今市值最高公司的10倍&#xff0c;是可以想象的&#xff0c;也是有…

一个在C#中集成Python的例子

一个在C#中集成Python的例子。在C#中可以执行Python脚本&#xff0c;在Python中也可以调用C#宿主中的功能&#xff08;clr.AddReference(Business)&#xff09;。 文件说明 Debug为执行目录 Mgr.exe为执行文件 Py\init.py为python初始化脚本 Py\Lib.zip为python需要的模块&…

大数据实训项目(小麦种子)-02、实训项目整体功能介绍与演示

文章目录 前言界面及功能描述实现功能描述技术选型界面展示首页界面功能1&#xff1a;HDFS&#xff0c;选择文件上传文件详细步骤 功能2&#xff1a;MapReduce预处理数据功能3&#xff1a;Hbase存储小麦种子数据并查询前10条记录功能4&#xff1a;Hive分析原始csv文件数据并ech…

【GO-OpenCV】go-cv快速配置

最近对golang实现目标检测心血来潮&#xff0c;尝试在没有sudo权限的平台配置go-cv,有所发现&#xff0c;索性多个平台都做尝试 安装Go语言&#xff08;Golang&#xff09; 通过包管理器安装&#xff08;适用于Debian/Ubuntu&#xff09;(有点慢) 更新包列表&#xff1a; sud…

简单的基于小波变换的图像压缩(Python)

2023 沃尔夫数学奖得主&#xff0c;给了杜克大学的Ingrid Daubechies&#xff08;多贝西&#xff09;教授 以色列沃尔夫基金会理事会成员 Michael Lin 教授在周二宣布: “Ingrid Daubechies is awarded the Wolf Prize for her work in the creation and development of wavel…

搭建k8s集群报错unknown command “\u00a0“ for “kubeadm init“

搭建k8s报错unknown command “\u00a0” for “kubeadm init” 网上搜了一下&#xff0c;是因为复制过来的命令前面包含了空格&#xff0c;将复制的命令放到idea可以清楚看到几个命令前面有空格&#xff0c;删除掉就好了&#xff0c;记录一下

设计模式-享元模式Flyweight(结构型)

享元模式(Flyweight) 享元模式是一种结构型模式&#xff0c;它主要用于减少创建对象的数量&#xff0c;减少内存占用。通过重用现有对象的方式&#xff0c;如果未找到匹配对象则新建对象。线程池、数据库连接池、常量池等池化的思想就是享元模式的一种应用。 图解 角色 享元工…

【团队成长】2024-24周周报-第一次组会人员分工48期推文预告

大家好&#xff01;我们是IndustryOR 团队&#xff0c;致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎/CSDN【运筹匠心】 。 记录人&#xff1a;张哲铭&#xff0c;算法专家&#xff0c;某互联网大厂 【团队成长/个人成长】系列的推文会以 【工作周报】 的方式记录Ind…

【机器学习】人工智能与气候变化:利用深度学习与机器学习算法预测和缓解环境影响

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f525;引言 1.1 背景介绍 1.2 人工智能与机器学习的崛起 1.3 本文内容概述 &#x1f528;气候变化的挑战 2.1 现今气候变化带来的影响和挑战 2.2 引发关注的气候变化趋势和数据 &#x1f916;人工智能…

使用SpringBoot对接Kafka

Kafka是什么&#xff0c;以及如何使用SpringBoot对接Kafka 一、Kafka与流处理 我们先来看看比较正式的介绍&#xff1a;Kafka是一种流处理平台&#xff0c;由LinkedIn公司创建&#xff0c;现在是Apache下的开源项目。Kafka通过发布/订阅机制实现消息的异步传输和处理。它具有高…

VMware Workstation安装及使用详细教程

如何安装VMware Workstation的详细教程 一、准备工作 1. 下载VMware Workstation&#xff1a; 访问VMware官方网站&#xff0c;找到VMware Workstation的下载页面。根据您的操作系统&#xff08;Windows或macOS&#xff09;选择相应的版本进行下载。确保您的计算机满足VMwar…

牛客小白月赛96 解题报告 | 珂学家

前言 题解 A. 最少胜利题数 签到 n1 len(set(input())) n2 len(set(input()))if n1 < n2:n1, n2 n2, n1print (-1 if n1 6 else n1 - n2 1)B. 最少操作次数 思路: 分类讨论 只有-1,0,1,2这四种结果 特判 01, 10 n int(input()) s input()# 枚举 from collectio…

vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT

MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件&#xff1b; 2、在src同级新建deploy文件夹&#xff0c;文件夹中新建pwd.txt和remote.sh文件&#xff1b; 3、配置好后&#xff0c;直接双击deploy.bat文…

Java_FileIO流

存储数据的方案 有些数据想长久保存起来&#xff0c;咋整&#xff1f; 文件时非常重要的存储方式&#xff0c;在计算机硬盘中。 即便断电&#xff0c;或者程序终止了&#xff0c;存储在硬盘文件中的数据也不会丢失。 File File 是Java.io.包下的类&#xff0c;File类对象&…