做賭石網(wǎng)站客服的經(jīng)驗電子商務(wù)seo實訓(xùn)總結(jié)
案例
@Cacheable
是 Spring Framework 提供的一個注解,用于在方法執(zhí)行前先檢查緩存,如果緩存中已存在對應(yīng)的值,則直接返回緩存中的值,而不執(zhí)行該方法體。如果緩存中不存在對應(yīng)的值,則執(zhí)行方法體,并將方法的返回值存入緩存供下次使用。
在 Spring Boot 中,@Cacheable
注解通常與緩存管理器一起使用,可以輕松地在方法級別上實現(xiàn)緩存功能,避免不必要的重復(fù)計算或查詢數(shù)據(jù)庫操作,從而提高應(yīng)用程序的性能和響應(yīng)速度。
如何使用?@Cacheable
?注解:
-
配置緩存管理器:首先,需要在 Spring Boot 應(yīng)用中配置一個緩存管理器,例如使用 EhCache、Caffeine、Redis 等。這通常可以通過添加相應(yīng)的依賴和配置來實現(xiàn)。
-
在方法上添加
@Cacheable
注解:將@Cacheable
注解添加到需要緩存的方法上,并指定緩存的名稱或緩存管理器的名稱,以及緩存的 key。
這種方式能夠顯著提高應(yīng)用程序的性能,特別是在需要頻繁訪問相同數(shù)據(jù)的場景下,通過緩存可以避免重復(fù)的耗時操作。
案例-生成驗證碼
這里有一個詞語
Caffenine 要記住
當(dāng)前默認(rèn)的緩存方案是Simple
緩存的使用案例——手機驗證碼
首先我們要封裝實體類
在domain包下創(chuàng)建類SMSCode
用lombok進行封裝
package com.example.demo.domain;import lombok.Data;@Data
public class SMSCode {private String tele;private String code;
}
在做一個業(yè)務(wù)層接口
放在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);
}
做業(yè)務(wù)層的實現(xiàn)類
即為剛剛的接口書寫實現(xiàn)類
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 {@Overridepublic String sendCodeToSMS(String tele) {return null;}@Overridepublic boolean checkCode(SMSCode smsCode) {return false;}
}
接下來書寫表現(xiàn)層代碼
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 {@Autowiredprivate SMSCodeService smsCodeService;@GetMappingpublic String getCode(String tele){String code =smsCodeService.sendCodeToSMS(tele);return code;}@PostMappingpublic boolean checkCode(SMSCode smsCode){return smsCodeService.checkCode(smsCode);}}
接下來就是最核心的內(nèi)容了
我們要在業(yè)務(wù)層去完善代碼
我們是不是需要一個驗證碼
我們?nèi)?chuàng)建一個工具類
去校驗對應(yīng)的驗證碼
創(chuàng)建一個工具類
注意的是
生成驗證碼的時候
要進行補全
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"));
// }}
當(dāng)然我們也可以拼接
把0 00 000 0000 00000放到一個數(shù)組里面去
然后判斷生成驗證碼的長度 然后直接進行拼接
接下來我們要去補全業(yè)務(wù)層的實現(xiàn)類
我們把緩存注入 掛到實現(xiàn)類上面去
接下來我們要去檢查緩存的依賴是否引入boot工程
看看啟動響應(yīng)類里面有沒有打開緩存功能
檢查完畢
我們直接給業(yè)務(wù)層實現(xiàn)類掛一個緩存就行
@Override
@Cacheable(value = "smsCode",key="#tele")
public String sendCodeToSMS(String tele) {String code=codeUtils.generator(tele);return code;
}
啟動我們的boot工程
我們打開postman
向服務(wù)器發(fā)起請求
依靠我們之前在表現(xiàn)層書寫的get請求
@GetMapping
public String getCode(String tele){String code =smsCodeService.sendCodeToSMS(tele);return code;
}
獲取到了驗證碼
但是這邊有個小問題
我們用同一個手機號發(fā)驗證碼
發(fā)起請求無論有多少次
獲取到的驗證碼都是一樣的
說明有緩存了
所以我們就思考到了
為什么我們每次靠手機號發(fā)送驗驗證碼的時候會進入60秒的冷卻等待時間
換個注解
僅僅往里面放緩存
@Override
// @Cacheable(value = "smsCode",key="#tele")@CachePut(value = "smsCode",key="#tele")public String sendCodeToSMS(String tele) {String code=codeUtils.generator(tele);return code;}
這樣就能獲取到了
手機驗證碼 每次這個數(shù)值 都會變化
案例-校驗功能
可以去CSDN學(xué)習(xí)下<artifactId>qcloudsms</artifactId>這個依賴
用到項目中,可以直接給手機發(fā)驗證碼(騰訊云SMS)
但是我們這邊會有一個小問題
運行g(shù)et的時候才會進行緩存
先執(zhí)行代碼在執(zhí)行注解
注解根本就沒有運行
注解沒運行 返回null
注解根本就沒加載
并沒有執(zhí)行spring容器管理
我們每次執(zhí)行的時候都是空指針 返回值都是空
作為ioc容器管理的對象,其中注解生效。但如果不使用對象直接調(diào)用當(dāng)然不生效
加了緩存的注解就相當(dāng)于會給當(dāng)前類生成一個代理對象, aop的思想, 在controller里調(diào)用方法和用this調(diào)用方法一個是走代理一個不走代理
同一個類中調(diào)用,沒有使用ioc容器中的對象調(diào)用方法,注解沒有被掃描,使用ioc容器的方法,注解才會被掃描
方法調(diào)用同實列的方法,代理失效
@Service也是個bean,但是寫在service下用this調(diào)用,只是走普通方法的調(diào)用,沒經(jīng)過spring容器,@Cacheable也就沒啟動,所以取不到緩存的值,我是這樣理解的
我想明白了,上面那個CachePut能使用是因為這個方法是在controller里面被調(diào)用的,用bean調(diào)用的,而這個是在service里面的方法間調(diào)用的,一個普通的類間的方法互相調(diào)用
我們的業(yè)務(wù)層核心邏輯
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 {@Autowiredprivate 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;}@Overridepublic 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去調(diào)用
這個方法
就能讓cacheCode
很巧合的加載進來
我們用postman獲取
這樣就代表我們的案例書寫成功
個人號推廣
博客主頁
多多!-CSDN博客
Web后端開發(fā)
https://blog.csdn.net/qq_30500575/category_12624592.html?spm=1001.2014.3001.5482
Web前端開發(fā)
https://blog.csdn.net/qq_30500575/category_12642989.html?spm=1001.2014.3001.5482
數(shù)據(jù)庫開發(fā)
https://blog.csdn.net/qq_30500575/category_12651993.html?spm=1001.2014.3001.5482
項目實戰(zhàn)
https://blog.csdn.net/qq_30500575/category_12699801.html?spm=1001.2014.3001.5482
算法與數(shù)據(jù)結(jié)構(gòu)
https://blog.csdn.net/qq_30500575/category_12630954.html?spm=1001.2014.3001.5482
計算機基礎(chǔ)
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