目录
缓存
Springboot使用缓存
Springboot中提供的缓存方案:
模拟案例:
Cache替换步骤
Ehcache例子
Redis例子
Memcache例子
缓存
缓存是一种介于数据永久存储与数据应用之间的数据临时存储介质。
使用缓存可以有效的减少低速数据读取过程的次数,提供系统性能。
缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间 。
Springboot使用缓存
1.导入依赖
2.在springboot启动类中添加注解开启缓存
参数value是存储空间的名字(可以随便起),key是唯一值,方便查找,我们通过key查找缓存
Springboot中提供的缓存方案:
模拟案例:
1.引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>compile</scope>
</dependency>
</dependencies>
2.启动cache
@SpringBootApplication
@EnableCaching
public class PracticeApplication {
public static void main(String[] args) {
SpringApplication.run(PracticeApplication.class, args);
}
}
3.写实体类
@Data
public class SMSCode {
private String tele;
private String code;
}
4.写业务层接口
public interface SMSCodeService {
public String sendCodeToSMS(String tele);
public boolean checkCode(SMSCode smsCode);
}
5.写对应实现类
@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);
}
}
6.写工具类(生成验证码算法)
@Component
public class CodeUtils {
private String [] patch={"00000","0000","000","00","0",""};
//设计验证码生成算法
public String generator(String tele){
int hash = tele.hashCode();
int encryption=2020666;
long result = hash ^ encryption;
long nowTime=System.currentTimeMillis();
result=result^nowTime;
long code=result%1000000;
code=code<0?-code:code;
String codeStr=code+"";
int length=codeStr.length();
return patch[length-1]+codeStr;
}
//需要被加载成bean,才能运行cache注解,不能在实现类中直接引用
@Cacheable(value = "smsCode",key = "#tele")//往缓存中放和取
public String get(String tele){
return null;
}
// public static void main(String[] args) {
// System.out.println(new CodeUtils().generator("15713001545"));
// }
}
7.写控制类
@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);
}
}
以上为简单验证码实现步骤。
Cache替换步骤
Ehcache例子
1.导入依赖
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
2.在核心配置文件中加入以下代码
spring:
cache:
type: ehcache
ehcache:
config: ehcache.xml
3.导入相应配置文件ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!-- 磁盘缓存位置 -->
<diskStore path="D:\ehcache"/>
<!-- 默认缓存 -->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。
仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。
仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
默认策略是LRU(最近最少使用)。
你可以设置为FIFO(先进先出)
或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
<defaultCache
maxElementsInMemory="10"
eternal="false"
diskPersistent="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"/>
<!-- smsCode缓存 -->
<cache name="smsCode"
maxElementsInMemory="10"
eternal="false"
diskPersistent="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
其他的不用动,实现方式都一致。
配置文件中的cache替换策略(操作系统中的缓存知识)
LRU:最近最久未使用算法 LFU:最不经常使用页置换算法
Redis例子
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置
spring:
cache:
type: redis
redis:
host: localhost
port: 6379
3.打开redis客户端和服务器端
4.redis配置解析
#Redis本地服务器地址,注意要开启redis服务,即那个redis-server.exe
spring.redis.host=127.0.0.1
#Redis服务器端口,默认为6379.若有改动按改动后的来
spring.redis.port=6379
#Redis服务器连接密码,默认为空,若有设置按设置的来
spring.redis.password=
#连接池最大连接数,若为负责则表示没有任何限制
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间,若为负责则表示没有任何限制
spring.redis.jedis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
spring:
redis:
# Redis本地服务器地址,注意要开启redis服务,即那个redis-server.exe
host: 127.0.0.1
# Redis服务器端口,默认为6379.若有改动按改动后的来
port: 6379
#Redis服务器连接密码,默认为空,若有设置按设置的来
password:
jedis:
pool:
# 连接池最大连接数,若为负数则表示没有任何限制
max-active: 8
# 连接池最大阻塞等待时间,若为负数则表示没有任何限制
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
Memcache例子
下载与安装(用管理员模式打开cmd)
实现步骤:
1.导入依赖
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.7</version>
</dependency>
2.在核心配置文件中自定义属性
memcached:
servers: localhost:11211
poolSize: 10
opTimeout: 3000
3.创建bean引用属性
@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XMemcachedProperties {
private String servers;
private int poolSize;
private long opTimeout;
}
4.编写配置类
@Configuration
public class XMemcachedConfig {
@Autowired
private XMemcachedProperties xMemcachedProperties;
@Bean
public MemcachedClient getMemcachedClient() throws IOException {
MemcachedClientBuilder memcachedClientBuilder=new XMemcachedClientBuilder(xMemcachedProperties.getServers());
memcachedClientBuilder.setConnectionPoolSize(xMemcachedProperties.getPoolSize());
memcachedClientBuilder.setOpTimeout(xMemcachedProperties.getOpTimeout());
MemcachedClient memcachedClient=memcachedClientBuilder.build();
return memcachedClient;
}
}
5.改写业务实现类
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
@Autowired
private CodeUtils codeUtils;
@Autowired
private MemcachedClient memcachedClient;
@Override
public String sendCodeToSMS(String tele) {
String code = codeUtils.generator(tele);
try {
memcachedClient.set(tele,0,code);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
}
return code;
}
@Override
public boolean checkCode(SMSCode smsCode) {
//取出内存中的验证码与传过来的验证码比较,看是否一致
String code = null;
try {
code = memcachedClient.get(smsCode.getTele()).toString();
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
}
return smsCode.getCode().equals(code);
}
}