SpringBoot 整合 EhCache

目前SpringBoot提供的 spring-boot-starter-cache 默认支持EhCache 2.x

Ehcache 3+,详细了解可访问https://www.ehcache.org

1. 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.9.2</version>
</dependency>

2. 添加配置文件

新建文件 src/main/resources/ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://www.ehcache.org/ehcache.xsd"
         updateCheck="false">
    <!--diskStore 磁盘存储位置-->
    <diskStore path="java.io.tmpdir/ehcache"/>
    <!--这个默认缓存在SpringBoot中不生效,但是必须配置-->
    <defaultCache/>
    <!--
    name:缓存名称,及注解中value的值
  maxElementsInMemory 在内存中缓存的element的最大数目
    maxEntriesLocalHeap:堆内存中最大缓存对象数,0表示没有限制
    eternal:是否永久缓存,一且设置了永久有效,timeout将不起作用
    timeToIdleSeconds:缓存的过期访问间隔,超过此间隔没有访问该缓存会过期,单位为秒
    timeToLiveSeconds:缓存的最大存活时间,单位为秒。timeToLiveSeconds必须大于等于timeToIdleSeconds才有意义
  overflowToDisk 表示当内存中的对象数量达到maxElementsinMemorv时,Ehcache是否将对象写到磁盘中
  diskExpiryThreadIntervalSeconds 表示磁盘失效线程运行时间间隅
  statistics 是否收集统计信息。如果需要监控缓存使用情况,应该打开这个选项。默认为关闭。
    -->
    <cache  name="custom"
      maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
      overflowToDisk="false"

  >
        <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>

 

3. 修改启动类

在启动类上添加 @EnableCaching 注解

package com.example.ehcache;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class EhcacheApplication {

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

}

4. 使用

  • 新建实体类
package com.example.ehcache.dao;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = -7596076576088137093L;
    private int id;
    private String name;
    private int age;
}
  • 接口
package com.example.ehcache.services;

import com.example.ehcache.dao.User;

public interface IUserService {
    public User findUserById(int id);
    public User findUser(int id);
    public void deleteUser(int id);
    public void deleteAll();
}
  •  服务
package com.example.ehcache.services.impl;

import com.example.ehcache.dao.User;
import com.example.ehcache.services.IUserService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
// 指明使用缓存的名称,这个配置可选,若不使用@CacheConfig,则直接在@Cacheable中指明即可.
// @CacheConfig(cacheNames = {"book_cache"})
public class UserService implements IUserService {
    @Override
    /*
    表示对该方法进行缓存,
    默认情况下缓存的key是方法参数,value是返回参数。
    当其他类调用该方法时,首先会根据调用参数查看缓存中是否有值,
    若有,则直接使用,该方法不会被执行,
    若无则执行该方法,并将成功后的值缓存起来。
    @Cacheable注解还有一个属性condition,用来描述缓存执行条件。
    如@Cacheable(key ="#d",condition ="#d%2==0"表示当id对2取余为0时,才进行缓存。
    */
    @Cacheable(value = "custom", key = "'user:'+#id")
    public User findUserById(int id) {
        System.out.println("get user " + id);
        return new User(id, "User" + id, 18);
    }

    @Override
    /*
    用户更新方法,
    每次执行时不检查缓存,直接执行方法,然后将执行结果缓存,
    如果该key已经被缓存起来了,则会覆盖之前的缓存,避免再次加载时获取到脏数据
    */
    @CachePut(value = "custom",key = "'user:'+#id")
    public User findUser(int id) {
        System.out.println("get user " + id);
        return new User(id, "User" + id, 19);
    }

    @Override
    /*
    用于删除方法,表示移除一个KEY对应缓存。
    @CacheEvict注解有两个特殊属性,allEntries和beforeInvocation 
    allEntries表示将所有缓存清空,默认为false; 
    beforeInvocation表示是否在方法执行之前清空所有缓存,默认为false,即在方法执行后清空缓存.
    */
    @CacheEvict(value = "custom",key = "'user:'+#id")
    public void deleteUser(int id) {

    }

    @Override
    @CacheEvict(value = "custom",allEntries = true)
    public void deleteAll() {

    }
}
  • 测试
package com.example.ehcache;

import com.example.ehcache.dao.User;
import com.example.ehcache.services.IUserService;
import net.sf.ehcache.CacheManager;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;

@SpringBootTest
class EhcacheApplicationTests {

    @Autowired
    private IUserService userService;

    @Test
    void contextLoads() {
        //第一次获取user1
        User user1 = userService.findUserById(1);
        System.out.println(user1);
        //第一次获取user2
        User user2 = userService.findUserById(2);
        System.out.println(user2);

        System.out.println("------------第一次获取user----------------");

        //从缓存中获取user1
        user1 = userService.findUserById(1);
        System.out.println(user1);

        System.out.println("--------------从缓存中获取user1--------------");

        //更新user1
        user1 = userService.findUser(1);
        System.out.println(user1);

        System.out.println("--------------更新user1--------------");

        //从缓存中删除user2
        userService.deleteUser(2);
        user2 = userService.findUserById(2);
        System.out.println(user2);

        System.out.println("--------------从缓存中删除user2--------------");

        //从缓存中删除所有user
        userService.deleteAll();
        //重新获取user1
        user1 = userService.findUserById(1);
        System.out.println(user1);
        //重新获取user2
        user2 = userService.findUserById(2);
        System.out.println(user2);
        System.out.println("--------------从缓存中删除所有user--------------");
    }

}
posted @ 2021-12-17 23:54  Bin_x  阅读(319)  评论(0编辑  收藏  举报