SpringBoot提供的缓存技术除了提供默认的缓存方案,还可以对其他缓存技术进行整合,统一接口,方便缓存技术
的开发与管理
默认的缓存技术
springboot自带的缓存
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
配置
spring:
cache:
type: simple
服务开启缓存
@EnableCaching
@SpringBootApplication
public class Springboot12AcheApplication {
}
业务层开启缓存
@Cacheable(value = “cacheSpace”,key = “#id”) 该方法第一次请求将id放入缓存,第二次请求在缓存里面取
value=缓存的名字
key=根据id取缓存
@Cacheable(value = "cacheSpace",key = "#id")
public Book getById(Integer id){
return bookDao.getById(id);
}
那同一个id需要不同的验证码时,这个就出现一直时同一个验证码
@CachePut(value = “smsCode”, key = “#tele”) 请求只将tele放入,不在里面取
测试
service
@Autowired
private CodeUtils codeUtils;
@Override
@CachePut(value = "smsCode", key = "#tele")
public String sendCodeToSMS(String tele) {
String generator = codeUtils.generator(tele);
return generator;
}
@Override
public boolean checkCode(SMSCode smsCode) {
String code = smsCode.getCode();
String cacheCode =codeUtils.get(smsCode.getTele());
return code.equals(cacheCode);
}
@Component
public class CodeUtils {
private final String[] patch = {"00000", "0000", "000", "00", "0", ""};
public String generator(String tel) {
int hash = tel.hashCode();
int encryption = 20001117;
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-1] + codeStr;
}
@Cacheable(value = "smsCode",key = "#tele")
public String get(String tele){
return null;
}
}
<dependency>
<groupId>net.sf.ehcachegroupId>
<artifactId>ehcacheartifactId>
dependency>
spring:
cache:
type: ehcache
ehcache:
config: ehcache.xml #文件的名称
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://www.ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="D:\ehcache"/>
<defaultCache
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU" />
<cache
name="smsCode"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
ehcache>
其他步骤与simple相同
配置
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
spring:
cache:
type: redis
redis:
use-key-prefix: true #是否使用将key前缀加上
time-to-live: 10s #设置存活时间
cache-null-values: false
key-prefix: aa #在key前缀在加上值,必须use-key-prefix是true才启用
jetCache对SpringCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表等功能
jetCache设定了本地缓存与远程缓存的多级缓存解决方案
本地缓存(local)
远程 缓存(remote)
依赖
<dependency>
<groupId>com.alicp.jetcachegroupId>
<artifactId>jetcache-starter-redisartifactId>
dependency>
jetcache:
remote:
default:
type: redis
host: localhost
port: 6379
poolConfig:
maxTotal: 50
sms: #代码中area的值
type: redis
host: localhost
port: 6379
poolConfig:
maxTotal: 50
@SpringBootApplication
@EnableCreateCacheAnnotation//启用缓存主开关
public class Springboot13JetcacheApplication {}
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
@Autowired
private CodeUtils codeUtils;
@CreateCache(area="default",name="jetCache",expire=3600,timeUnit= TimeUnit.SECONDS)
private Cache<String, String> jetCache;
@CreateCache(area="sms",name="jetCache",expire=3600,timeUnit = TimeUnit.SECONDS)
private Cache<String, String> jetCache;
@Override
public String sendCodeToSMS(String tele) {
String code = codeUtils.generator(tele);
jetCache.put(tele, code);
return code;
}
@Override
public boolean checkCode(SMSCode smsCode) {
String code = jetCache.get(smsCode.getTele());
return smsCode.getCode().equals(code);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ptOOc2zp-1653027060722)(img/SpringBoot/image-20220519191857846.png)]
jetcache:
local:
default:
type: linkedhashmap
keyConvertor: fastjson
其他都一样
@CreateCache(area="default",name = "jetCache_",expire=3600,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL) //cacheType 指定哪个方案
private Cache<String, String> jetCache;
配置范例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0HBYpbKF-1653027060723)(img/SpringBoot/image-20220519192715103.png)]
配置说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MqT8xHqU-1653027060723)(img/SpringBoot/image-20220519192801555.png)]
@SpringBootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.xu")//开启方法缓存,两个注解都需要
public class Springboot13JetcacheApplication {}
在service的方法中加上@Cached(name = "book",key = "#id",expire = 3600,cacheType = CacheType.REMOTE)
可以使用远程或者本地
报错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2m9kysps-1653027060723)(img/SpringBoot/image-20220519193401919.png)]
修改
jetcache:
remote:
default:
type: redis
host: localhost
port: 6379
keyConvertor: fastjson #空指针异常
poolConfig:
maxTotal: 50
序列化异常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBjxAvg1-1653027060724)(img/SpringBoot/image-20220519193705884.png)]
redis不支持存储对象,pojo实现序列化,并在配置中加入
public class SMSCode implements Serializable {}
jetcache:
remote:
default:
type: redis
host: localhost
port: 6379
keyConvertor: fastjson
valueEncode: java
valueDecode: java
poolConfig:
maxTotal: 50
当方法有更新数据的时候
在更新的方法加上
@CacheUpdate(name = "book_",key = "#book.id",value = "#book")
key,表示的缓存中的key,value表示你更新完的内容
删除缓存
@CacheInvalidate(name = "book_",key = "#id")
在缓存注解上加上缓存会刷新不使用
@CacheRefresh(refresh = 10)
<dependency>
<groupId>net.oschina.j2cachegroupId>
<artifactId>j2cache-coreartifactId>
<version>version>
dependency>
<dependency>
<groupId>net.oschina.j2cachegroupId>
<artifactId>j2cache-spring-boot2-starterartifactId>
<version>version>
dependency>
j2cache:
config-location: j2cache.properties
j2cache.properties
#1级缓存
j2cache.L1.provider_class=ehcache
ehcache.configXml=ehcache.xml
#2级缓存
j2cache.L2.provider_class=net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section=redis
redis.hosts=localhost:6379
#1级缓存中的数据如何到达2级缓存
j2cache.broadcast=net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://www.ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="D:\ehcache"/>
<defaultCache
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
ehcache>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-58nG4UXW-1653027060724)(img/SpringBoot/image-20220520075823756.png)]
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
@Autowired
private CodeUtils codeUtils;
@Autowired
private CacheChannel cacheChannel;
@Override
public String sendCodeToSMS(String tele) {
String code = codeUtils.generator(tele);
cacheChannel.set("sms",tele,code);
return code;
}
@Override
public boolean checkCode(SMSCode smsCode) {
String code = cacheChannel.get("sms", smsCode.getTele()).asString();
return smsCode.getCode().equals(code);
}
}