深圳幻海软件技术有限公司 欢迎您!

SpringBoot集成Ehcache使用教程

2023-02-28

前言在平时做项目都要用到缓存,方便临时存储一些数据,加快访问速度。如果项目比较小,搭建redis服务,后期在维护上比较麻烦。今天分享一个SpringBoot集成Ehcache实现缓存的教程,适合中小项目中使用。准备工作1、maven中导入依赖复制<!--开启Springbootcache缓存-

前言

在平时做项目都要用到缓存,方便临时存储一些数据,加快访问速度。如果项目比较小,搭建redis服务,后期在维护上比较麻烦。今天分享一个SpringBoot集成Ehcache实现缓存的教程,适合中小项目中使用。

准备工作

1、maven中导入依赖

<!--开启Springboot cache 缓存 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- ehcache 缓存 -->
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.1.1</version>
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

2、启动类上增加缓存注解

@MapperScan("com.zhangls.ehcache.dao.**")
@SpringBootApplication
@EnableCaching
public class EhcacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(EhcacheApplication.class, args);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

3、配置Ehcache

在resources下增加ehcache.xml文件,配置如下:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.ehcache.org/v3"
        xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
        xsi:schemaLocation="
            http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
            http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
    <service>
        <!--开启service注解-->
        <jsr107:defaults enable-statistics="true"/>
    </service>
    <!-- user 为该缓存名称 对应@Cacheable的属性cacheNames-->
    <cache alias="UserCache">
        <!-- 指定缓存 key 类型,对应@Cacheable的属性key -->
        <key-type>java.lang.String</key-type>
        <!-- 配置value类型 -->
        <value-type>com.zhangls.ehcache.entity.User</value-type>
        <expiry>
            <!-- 缓存 ttl,单位为分钟,现在设置的是1分钟 -->
            <ttl unit="minutes">1</ttl>
        </expiry>
        <resources>
            <!-- 分配资源大小 -->
            <heap unit="entries">2000</heap>
            <offheap unit="MB">100</offheap>
        </resources>
    </cache>
    <!--这里可以配置N个 。。。。 不同的cache 根据业务情况配置-->
</config>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

4、application.yml中配置

spring:
  cache:
    jcache:
      config: classpath:ehcache.xml
  • 1.
  • 2.
  • 3.
  • 4.

注意事项

1.Ehcache 会在一定的规则下会序列化后存储到硬盘上,因此缓存对象必须支持序列化。

public class User implements Serializable{}
  • 1.

2.Spring定义了缓存接口Cache和管理缓存控制器 CacheManager,路径为:

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
  • 1.
  • 2.

使用方法--手动管理方式

@Autowired
private CacheManager cacheManager;
@GetMapping("/addCache")
public String addCache() {
    User user = new User();
    user.setUsername("九天银河聊编程");
    user.setAge(34);
    Cache cache = cacheManager.getCache("UserCache");
    cache.put("user", user);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date now = new Date();
    return sdf.format(now) + ":  " + "保存成功";
}

@GetMapping("/getCache")
public String getCache() {
    Cache cache = cacheManager.getCache("UserCache");
    Cache.ValueWrapper res = cache.get("user");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date now = new Date();
    if (null != res) {
        User user = (User) res.get();//这里获取  ehcache.xml 中 <cache>  value-type 定义的类型,可以直接强转。
        return sdf.format(now) + ":  " + "姓名:" + user.getUsername() + ",年龄:" + user.getAge();
    }
    return sdf.format(now) + ":  " + "没有找到缓存!";
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

运行结果

执行:127.0.0.1:8080/ehcache/addCache。

执行:127.0.0.1:8080/ehcache/getCache。

1分钟后执行127.0.0.1:8080/ehcache/getCache,缓存失效。

使用方法--@Cacheable 注解方式

service代码:

@Service
public class ImPersonServiceImpl implements ImPersonService{
    @Resource
    private PersonMapper personMapper;
    @Override
    @Cacheable(cacheNames = "PersonCache", key = "#personId")
    public ImPerson selectByPrimaryKey(String personId){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();
        System.out.println(sdf.format(now) + ":  未命中缓存,请求数据库");
        return personMapper.selectByPrimaryKey(personId);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

controller代码:

    @GetMapping("/getCachePerson")
    public ImPerson getCachePerson() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = new Date();
        System.out.println(sdf.format(start) + ":执行开始------");
        ImPerson person = imPersonService.selectByPrimaryKey("1");
        Date end = new Date();
        System.out.println(sdf.format(end) + ":执行结束------");
        return person;
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

执行两次:127.0.0.1:8080/ehcache/getCachePerson。

控制台只打印一次SQL信息,说明第二次请求从缓存中获取。

@Cacheable属性说明

  • cacheNames/value :用来指定缓存组件的名字。
  • key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)。
  • keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用。
  • cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
  • condition :可以用来指定符合条件的情况下才缓存,如下表示id>1的进行缓存。
 @Cacheable(cacheNames = "PersonCache", condition  = "#id > 1")
  • 1.
  • unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
  • sync :是否使用异步模式。

踩坑说明

Spring 缓存注解是基于Spring AOP切面,必须走代理才能生效。同类调用或者子类调用父类带有缓存注解的方法时属于内部调用,没有走代理,所以注解不会生效。所以在使用@Cacheable时,一定要放在在service的实现类中进行调用。