前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot 缓存

SpringBoot 缓存

作者头像
.29.
发布2024-04-25 20:23:21
860
发布2024-04-25 20:23:21
举报
文章被收录于专栏:个人技术博客个人技术博客
目录
  • 一、缓存的作用
  • 二、SpringBoot启用缓存
  • 三、SpringBoot可整合的缓存技术
  • 四、缓存使用案例——收集验证码
    • 实体类开发
    • 业务层开发
    • 工具类(生成验证码)
    • 控制层开发
    • SpringBoot启动类
    • 测试
  • 五、变更缓存供应商Ehcache

一、缓存的作用


缓存

  • 缓存时一种介于数据永久存储介质与数据应用之间的数据临时存储介质
  • 使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能
  • 缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间

二、SpringBoot启用缓存


SpringBoot提供了缓存技术,方便缓存的使用

  • 启用缓存
  • 设置进入缓存的数据
  • 设置读取缓存的数据

pom.xml导入缓存相关的起步依赖

代码语言:javascript
复制
        <!--缓存功能的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

SpringBoot启动类,添加@EnableCaching注解,启用缓存

代码语言:javascript
复制
@SpringBootApplication
@EnableCaching        //此注解表示开启缓存功能
public class Springboot4CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot4CacheApplication.class, args);
    }

}

业务层组件,使用@Cacheable注解

value属性:存放缓存的位置,可随意定义

key属性:使用 # + 参数名 的方式设置缓存的数据

代码语言:javascript
复制
@Override
@Cacheable(value = "cacheSpace",key = "#id")
public Book getById(Integer id){
    return bookMapper.selectById(id);
}

三、SpringBoot可整合的缓存技术


  • SpringBoot提供的缓存技术除了提供默认的方案,还可以对其他缓存技术进行整合,统一接口,方便缓存技术的开发与管理。

常见的SpringBoot可整合的缓存技术

  • Generic
  • JCache
  • Ehcache
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffenine
  • Simple(默认)
  • memcached

四、缓存使用案例——收集验证码


需求

  • 输入手机号获取验证码,组织文档以短信形式发送给用户(页面模拟)
  • 输入手机号和验证码以验证结果

需求分析

  • 提供Controller组件,传入手机号,业务层通过手机号计算出独有的6位数验证码数据,存入缓存后返回此数据;
  • 提供Controller组件,传入手机号与验证码,业务层通过手机号从缓存中读取验证码,与输入的验证码进行比对,返回最终结果;

实体类开发

lombok快速开发实体类

代码语言:javascript
复制
        <!--导入lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

代码语言:javascript
复制
import lombok.Data;

/**
 * @author .29.
 * @create 2023-04-02 22:08
 * 使用@Data注解,提供Getter、Setter和toString()
 */
@Data
public class SMSCode {
    //电话号码
    private String phoneNumber;
    //验证码
    private String code;
}

业务层开发

业务层接口

代码语言:javascript
复制
/**
 * @author .29.
 * @create 2023-04-02 22:12
 */

public interface SMSCodeService {
    //模拟向sm卡发送验证码
    public String sendCodeToSMS(String phoneNumber);

    //验证验证码是否正确
    public boolean checkCode(SMSCode smsCode);
}

业务层接口实现类

  • 业务层组件中,使用了缓存功能,缓存功能的开启需要在SpringBoot工程的启动类中使用@EnableCaching开启缓存功能。
代码语言:javascript
复制
/**
 * @author .29.
 * @create 2023-04-02 22:15
 */
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils utils;  //自动装配工具类对象(工具类中提供了生成验证码的算法)

    @Override
    //@Cacheable注解不适用,缓存会被读取,导致前后两次验证码重复
    //@Cacheable(value="smsCode",key = "#phoneNumber")
    //@CachePut注解,缓存只可放不可读
    @CachePut(value="smsCode",key = "#phoneNumber")
    public String sendCodeToSMS(String phoneNumber) {
        return utils.generator(phoneNumber);
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        //取出内存中的验证码与传递过来的参数比对,如果相同,返回true
        String code = smsCode.getCode();
        String cacheCode = utils.get(smsCode.getPhoneNumber());
        return cacheCode.equals(code);
    }
}

工具类(生成验证码)

工具类实现

代码语言:javascript
复制
/**
 * @author .29.
 * @create 2023-04-02 22:26
 */
@Component
public class CodeUtils {
    //为不足六位数的验证码补0用
    private String[] patch = {"000000","00000","0000","000","00","0",""};

    //加密,生成验证码
    public String generator(String phoneNumber){
        //获取手机号的hashCode值
        int hash = phoneNumber.hashCode();
        //设置一个加密码
        int encryption = 20230209;
        //获取第一次加密结果
        long result = hash ^ encryption;
        //第二次加密,第一次加密结果与当前时间进行异或操作
        long nowTime = System.currentTimeMillis();
        result = result ^ nowTime;
        //获取第二次加密结果的后六位
        long code = result % 1000000;
        code = code < 0 ? -code : code;//避免验证码为负值
        //转化为字符串
        String codeStr = code+"";
        int len = codeStr.length();
        return patch[len]+codeStr;
    }

    //设置phoneNumber的缓存,方法返回值为null,有缓存则返回缓存数据,没有才返回null
    @Cacheable(value="smsCode",key = "#phoneNumber")
    public String get(String phoneNumber){
        return null;
    }

}

控制层开发

代码语言:javascript
复制
/**
 * @author .29.
 * @create 2023-04-02 22:16
 */
//用于标记控制器类。@RestController 是 @Controller 和 @ResponseBody 的组合注解,用于标记 RESTful 风格的控制器类。
@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService service; //自动装配业务层组件

    //获取验证码
    @GetMapping
    public String getCode(String phoneNumber){
        String code = service.sendCodeToSMS(phoneNumber);
        return code;
    }

    //判断验证码是否正确
    @PostMapping
    public boolean checkCode(SMSCode smsCode){
        boolean result = service.checkCode(smsCode);
        return result;
    }
}

SpringBoot启动类

  • 注意要开启缓存功能
代码语言:javascript
复制
@SpringBootApplication
@EnableCaching        //此注解表示开启缓存功能
public class Springboot4CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot4CacheApplication.class, args);
    }

}

测试

运行案例工程

在这里插入图片描述
在这里插入图片描述

使用国产postMAN测试功能

  • 使用页面模拟接收验证码:(每次发送请求,验证码都不会重复)

在这里插入图片描述
在这里插入图片描述
  • 模拟验证码比对校验:(只有当次手机号码与验证码匹配,才会返回true)

在这里插入图片描述
在这里插入图片描述

五、变更缓存供应商Ehcache


pom.xml导入Ehcache依赖

代码语言:javascript
复制
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

application.yml配置文件

  • 设置使用ehcache的缓存
代码语言:javascript
复制
spring:
  cacahe:
    type: ehcache

配置Ehcache的xml配置文件

  • 其中的name属性值,需要保证与你注解中设置的缓存位置一致
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <diskStore path="D:\ehcache" />

    <!--默认缓存策略 -->
    <!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
    <!-- diskPersistent:是否启用磁盘持久化-->
    <!-- maxElementsInMemory:最大缓存数量-->
    <!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
    <!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
    <!-- timeToLiveSeconds:最大存活时间-->
    <!-- memoryStoreEvictionPolicy:缓存清除策略-->
    <defaultCache
        eternal="false"
        diskPersistent="false"
        maxElementsInMemory="1000"
        overflowToDisk="false"
        timeToIdleSeconds="60"
        timeToLiveSeconds="60"
        memoryStoreEvictionPolicy="LRU" />

    <cache
        name="smsCode"  
        eternal="false"
        diskPersistent="false"
        maxElementsInMemory="1000"
        overflowToDisk="false"
        timeToIdleSeconds="10"
        timeToLiveSeconds="10"
        memoryStoreEvictionPolicy="LRU" />

</ehcache>
  • 完成上述配置,缓存技术也就更换完成了。
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 一、缓存的作用
  • 二、SpringBoot启用缓存
  • 三、SpringBoot可整合的缓存技术
  • 四、缓存使用案例——收集验证码
    • 实体类开发
      • 业务层开发
        • 工具类(生成验证码)
          • 控制层开发
            • SpringBoot启动类
              • 测试
              • 五、变更缓存供应商Ehcache
              相关产品与服务
              验证码
              腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
              http://www.vxiaotou.com