【Spring Boot】Ehcache缓存

1. 前言

本文介绍在Spring Boot 2.1.0.RELEASE中引入Ehcache缓存。

2. 引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

3. 配置

3.1 application.yml

添加ehcache配置。

spring:
  cache:
    type: ehcache
    ehcache:
      config: classpath:ehcache.xml

3.2 ehcache.xml

<!-- ehcache配置 -->
<ehcache
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">
    <!--缓存路径,用户目录下的base_ehcache目录-->
    <diskStore path="user.home/base_ehcache"/>

    <defaultCache
            maxElementsInMemory="20000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <!--
    缓存文件名:user,同样的可以配置多个缓存
    maxElementsInMemory:内存中最多存储
    eternal:外部存储
    overflowToDisk:超出缓存到磁盘
    diskPersistent:磁盘持久化
    timeToLiveSeconds:缓存时间
    diskExpiryThreadIntervalSeconds:磁盘过期时间
    -->
    <cache name="user"
           maxElementsInMemory="20000"
           eternal="true"
           overflowToDisk="true"
           diskPersistent="false"
           timeToLiveSeconds="0"
           diskExpiryThreadIntervalSeconds="120"/>

</ehcache>

3.3 @EnableCaching

Application启动类添加@EnableCaching注解。

4. 使用

不管是Redis缓存,还是Ehcache缓存,Spring统一提供@CachePut@Cacheable@CacheEvict注解进行存取操作。

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    /**
     * 模拟数据库
     */
    private static final Map<Long, User> DATABASES = Maps.newConcurrentMap();

    /**
     * 初始化数据
     */
    static {
        DATABASES.put(1L, new User(1L, "user1"));
        DATABASES.put(2L, new User(2L, "user2"));
        DATABASES.put(3L, new User(3L, "user3"));
    }

    /**
     * 保存或修改用户
     *
     * @param user 用户对象
     * @return 操作结果
     */
    @CachePut(value = "user", key = "#user.id")
    @Override
    public User saveOrUpdate(User user) {
        DATABASES.put(user.getId(), user);
        log.info("保存用户【user】= {}", user);
        return user;
    }

    /**
     * 获取用户
     *
     * @param id key值
     * @return 返回结果
     */
    @Cacheable(value = "user", key = "#id")
    @Override
    public User get(Long id) {
        // 我们假设从数据库读取
        log.info("查询用户【id】= {}", id);
        return DATABASES.get(id);
    }

    /**
     * 删除
     *
     * @param id key值
     */
    @CacheEvict(value = "user", key = "#id")
    @Override
    public void delete(Long id) {
        DATABASES.remove(id);
        log.info("删除用户【id】= {}", id);
    }
}

5. 测试

@Test
public void getTwice() {
    // 模拟查询id为1的用户
    User user1 = userService.get(1L);
    log.debug("【user1】= {}", user1);

    // 再次查询
    User user2 = userService.get(1L);
    log.debug("【user2】= {}", user2);
    // 查看日志,只打印一次日志,证明缓存生效
}

/**
 * 先存,再查询,查看日志验证缓存
 */
@Test
public void getAfterSave() {
    userService.saveOrUpdate(new User(4L, "user4"));

    User user = userService.get(4L);
    log.debug("【user】= {}", user);
    // 查看日志,只打印保存用户的日志,查询是未触发查询日志,因此缓存生效
}

/**
 * 测试删除,查看redis是否存在缓存数据
 */
@Test
public void deleteUser() {
    // 查询一次,使ehcache中存在缓存数据
    userService.get(1L);
    // 删除,查看ehcache是否存在缓存数据
    userService.delete(1L);
}

文章作者: 叶遮沉阳
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 叶遮沉阳 !
  目录