SpringBoot Ehcache

8 篇文章 0 订阅
8 篇文章 0 订阅

springboot+ehcach

1、ehcache依赖:
<!-- Spring Boot 缓存支持启动器 -->
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
   </dependency>
   <!-- Ehcache 坐标 -->
   <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
   </dependency>

具体的pom文件

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>

   <!--事务 @Transactional-->
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.1.8.RELEASE</version>
   </dependency>

   <!--集成swagger-API-->
   <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-models</artifactId>
      <!--<scope>compile</scope>-->
   </dependency>
   <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-annotations</artifactId>
      <!--<scope>compile</scope>-->
   </dependency>
   <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
   </dependency>
   <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <exclusions>
         <exclusion>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
         </exclusion>
         <exclusion>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
         </exclusion>
      </exclusions>
   </dependency>

   <!-- Spring Boot 缓存支持启动器 -->
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
   </dependency>
   <!-- Ehcache 坐标 -->
   <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
   </dependency>

   </dependencies>
2、创建ehcache.xml文件

在resources下面创建ehcache.xml,复制以下内容。

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

    <!--这个是磁盘存储路径,当内存缓存满了的时候,就会往这里面放,java.io.tmpdir是操作系统缓存的临时目录,不同操作系统缓存目录不一样。-->
    <diskStore path="java.io.tmpdir"/>

    <!--defaultCache:echcache的默认缓存策略  -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>

    <!--测试:自定义缓存策略1-->
    <cache name="users"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>
    <!--测试:自定义缓存策略2-->
    <cache name="users2"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>

</ehcache>




    <!--
    maxElementsInMemory      内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况
                             1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中
                             2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素
    overflowToDisk           内存不足时,是否启用磁盘缓存
    eternal                  缓存中对象是否永久有效
    timeToIdleSeconds        缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除
    timeToLiveSeconds        缓存数据的总的存活时间(单位:秒),仅当eternal=false时使用,从创建开始计时,失效结束。
    maxElementsOnDisk        磁盘缓存中最多可以存放的元素数量,0表示无穷大
    diskExpiryThreadIntervalSeconds   磁盘缓存的清理线程运行间隔,默认是120秒
    memoryStoreEvictionPolicy   内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存  共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出)

    另外,defaultCache是默认缓存方式,cache是自定义的缓存方式,自行设置name

    -->

    <!--timeToIdleSeconds 当缓存闲置n秒后销毁 -->
    <!--timeToLiveSeconds 当缓存存活n秒后销毁 -->
    <!-- 缓存配置
        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:内存数量最大时是否清除。 -->

3、参考ehcache.xml配置文件详解

​ diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。
​ defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
​ name:缓存名称。
​ maxElementsInMemory:缓存最大数目
​ maxElementsOnDisk:硬盘最大缓存个数。
​ eternal:对象是否永久有效,一但设置了,timeout将不起作用。
​ overflowToDisk:是否保存到磁盘,当系统宕机时
​ timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
​ timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
​ diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
​ diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
​ diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
​ memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
​ clearOnFlush:内存数量最大时是否清除。
​ FIFO,first in first out,先进先出。
​ LFU, Less Frequently Used,一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
​ LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

4、添加启用缓存
@EnableCaching  //添加启用缓存

Application.java

@SpringBootApplication
@EnableCaching  //添加启用缓存
public class SpringbootTestCacheApplication {

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

}
5、EhcacheController.java
package com.dist.controller;

import com.dist.entity.UserEntity;
import com.dist.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

/**Ehcache 缓存
 * @author zhengja@dist.com.cn
 * @data 2019/8/15 10:51
 */
@Api(tags = {"EhcacheController"},description = "Ehcache 缓存")
@RestController
@RequestMapping(value = "rest/ehcache")
public class EhcacheController {

    @Autowired
    @Qualifier(value = "userServiceImpl")
    private UserService userService;

    @ApiOperation(value = "保存缓存-users",httpMethod = "GET")
    @RequestMapping(value = "getuserbyid",method = RequestMethod.GET)
    public Object getUserById(@ApiParam(value = "查询字段:id") @RequestParam Integer id){

        //缓存存放的目录
        String userHome = System.getProperty("user.home");
        String userDir = System.getProperty("user.dir");
        String tmpDir = System.getProperty("java.io.tmpdir");

        System.out.println("userHome:"+userHome);
        System.out.println("userDir:"+userDir);
        System.out.println("tmpDir:"+tmpDir);

        return this.userService.getUserById(id);
    }

    @ApiOperation(value = "清除缓存-users",httpMethod = "POST")
    @RequestMapping(value = "saveuser",method = RequestMethod.POST)
    public void saveUser(@ApiParam(value = "参考:Model") @RequestBody UserEntity userEntity){
        this.userService.saveUser(userEntity);
    }


    @ApiOperation(value = "模拟数据库保存",httpMethod = "GET")
    @RequestMapping(value = "save",method = RequestMethod.GET)
    public String save(@ApiParam(value = "typeId") @RequestParam String typeId) {
        return this.userService.save(typeId);
    }


    @ApiOperation(value = "模拟数据库更新",httpMethod = "GET")
    @RequestMapping(value = "update",method = RequestMethod.GET)
    public String update(@ApiParam(value = "typeId") @RequestParam String typeId) {
        return this.userService.update(typeId);
    }

    @ApiOperation(value = "模拟数据库删除",httpMethod = "GET")
    @RequestMapping(value = "delete",method = RequestMethod.GET)
    public String delete(@ApiParam(value = "typeId") @RequestParam String typeId) {
        return this.userService.delete(typeId);
    }

    @ApiOperation(value = "模拟数据库查询",httpMethod = "GET")
    @RequestMapping(value = "select",method = RequestMethod.GET)
    public String select(@ApiParam(value = "typeId") @RequestParam String typeId) {
        return this.userService.select(typeId);
    }

    @ApiOperation(value = "复杂的缓存规则",httpMethod = "GET")
    @RequestMapping(value = "selectbyname",method = RequestMethod.GET)
    public UserEntity selectByName(@ApiParam(value = "name") @RequestParam String name) {
        return this.userService.selectByName(name);
    }

}
6、接口UserService.java
package com.dist.service;

import com.dist.entity.UserEntity;

/**
 * @author zhengja@dist.com.cn
 * @data 2019/8/15 10:36
 */
public interface UserService {

    /**
     * 测试 ehcache 保存缓存
     * @param id
     * @return
     */
    UserEntity getUserById(Integer id);

    /**
     * 测试 ehcache 清楚缓存
     * @param userEntity
     */
    void saveUser(UserEntity userEntity);


    /**
     * 以下为模拟数据库操作
     * @param typeId
     * @return
     */
    String save(String typeId);

    String update(String typeId);

    String delete(String typeId);

    String select(String typeId);

    /**
     * 复杂的缓存
     * @param name
     * @return
     */
    UserEntity selectByName(String name);
}
7、实现类UserServiceImpl.java
package com.dist.service.Impl;

import com.dist.entity.UserEntity;
import com.dist.service.UserService;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author zhengja@dist.com.cn
 * @data 2019/8/15 10:36
 */
@Service(value = "userServiceImpl")
@Transactional     //事务,表示该类下所有的都受事务控制
@CacheConfig(cacheNames = "users2")
public class UserServiceImpl implements UserService {

    /**
     * 测试 ehcache 保存缓存
     *
     * @Cacheable 可以标记在一个方法上,也可以标记在一个类上
     * 流程:被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法
     * 如何缓存:缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果
     * @Cacheable可以指定三个属性,value、key和condition
     *  value属性指定cache的名称(即选择ehcache.xml中哪种缓存方式存储)
     *  key(默认策略)属性是用来指定Spring缓存方法的返回结果时对应的key的,该属性支持SpringEL表达式;可使用“#参数名”或者“#p参数index”
     *  condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 如:condition = "#userName.length()>2"
     *
     * @param id
     * @return
     */
    //@Cacheable(value = "users")
    @Cacheable(value = {"users","users2"},key = "#id",condition = "#id=1")
    @Override
    public UserEntity getUserById(Integer id) {

        UserEntity userEntity = new UserEntity();
        userEntity.setId(id);
        userEntity.setName("张三");
        userEntity.setAge(23);

        System.out.println("id值:"+id);

        return userEntity;
    }

    /**
     * 测试 ehcache 清楚缓存
     * @param userEntity
     */
    @CacheEvict(value = "users",allEntries = true)
    @Override
    public void saveUser(UserEntity userEntity){
        System.out.println(userEntity);
    }


    /**
     * 以下是key 实例
     * @param id
     * @return
     */
    @Cacheable(value="users", key="#id")
    public UserEntity find1(Integer id) {
        return null;
    }

    @Cacheable(value="users", key="#p0")
    public UserEntity find2(Integer id) {
        return null;
    }

    @Cacheable(value="users", key="#user.id")
    public UserEntity find3(UserEntity user) {
        return null;
    }

    @Cacheable(value="users", key="#p0.id")
    public UserEntity find4(UserEntity user) {
        return null;
    }


    /**
     * 以下是模拟测试
     * @param typeId
     * @return
     */
    @Cacheable
    @Override
    public String save(String typeId) {
        System.out.println("save()执行了=============");
        return "模拟数据库保存";
    }

    @CachePut
    @Override
    public String update(String typeId) {
        System.out.println("update()执行了=============");
        return "模拟数据库更新";
    }

    @CacheEvict
    @Override
    public String delete(String typeId) {
        System.out.println("delete()执行了=============");
        return "模拟数据库删除";
    }

    @Cacheable
    @Override
    public String select(String typeId) {
        System.out.println("select()执行了=============");
        return "模拟数据库查询";
    }

    /**
     * 复杂的缓存:高速缓存
     * @param name
     * @return
     */
    @Caching(
            cacheable = {
                    @Cacheable(cacheNames = {"users"},key="#name") //(1)根据name查询user
            },
            put = {
                    @CachePut(cacheNames = {"users"},key="#result.id") //(2) 根据id查询user 以另一种key将查询出的结果缓存到缓存中
            }
    )
    @Override
    public UserEntity selectByName(String name) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1);
        userEntity.setName(name);
        userEntity.setAge(23);
        System.out.println("进入方法:"+name);
        return userEntity;
    }

}
************************本片文章阅读结束************************

作者:宇宙小神特别萌
个人博客:www.zhengjiaao.cn
Gitee 仓库:https://gitee.com/zhengjiaao
Github 仓库:https://github.com/zhengjiaao?tab=repositories
描述:喜欢文章的点赞收藏一下,关注不迷路,避免以后找不到哦,大家遇到问题下方可评论

************************本片文章阅读结束************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇宙小神特别萌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值