目录

缓存

Springboot使用缓存

Springboot中提供的缓存方案:

 模拟案例:

Cache替换步骤

Ehcache例子

Redis例子

Memcache例子


缓存

缓存是一种介于数据永久存储与数据应用之间的数据临时存储介质。

使用缓存可以有效的减少低速数据读取过程的次数,提供系统性能。

缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间 。

Springboot使用缓存

1.导入依赖

spring boot 延迟加载 springboot启动加载缓存_spring boot 延迟加载

2.在springboot启动类中添加注解开启缓存

spring boot 延迟加载 springboot启动加载缓存_java_02

 

spring boot 延迟加载 springboot启动加载缓存_缓存_03

参数value是存储空间的名字(可以随便起),key是唯一值,方便查找,我们通过key查找缓存

Springboot中提供的缓存方案:

spring boot 延迟加载 springboot启动加载缓存_spring boot 延迟加载_04

 模拟案例:

spring boot 延迟加载 springboot启动加载缓存_学习_05

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替换策略(操作系统中的缓存知识)

spring boot 延迟加载 springboot启动加载缓存_java_06

 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)

spring boot 延迟加载 springboot启动加载缓存_spring boot 延迟加载_07

 

spring boot 延迟加载 springboot启动加载缓存_java_08

 实现步骤:

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);
    }
}