springboot 整合 ehcache3.x 作为缓存

lshan / 2024-11-20 / 原文

 

版本:

springboot2.3.12 + ehcache3.x  +  

app + @EnableCaching
application.properties + spring.cache.type=JCACHE

 

依赖:

        <!-- 缓存 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
          </dependency>
          <!-- ehcache -->
          <dependency>
              <groupId>org.ehcache</groupId>
              <artifactId>ehcache</artifactId>
              <version>3.10.8</version>
          </dependency>
         <dependency>
              <groupId>javax.cache</groupId>
              <artifactId>cache-api</artifactId>
          </dependency>

 

 

 

package com.trt.meditation.common.config;

import com.alibaba.fastjson.JSON;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

/***************************
 *<pre>
 * @Project Name : bk
 * @Package      : com.trt.meditation.common.config
 * @File Name    : MyEhcacheConfig
 * @Author       :  Sea
 * @Mail         :  lshan523@163.com
 * @Date         : 2024/10/24 14:29
 * @Purpose      :
 * @History      :
 *
 * springboot2.3.12 + ehcache3  +  @EnableCaching   +  config + spring.cache.type=JCACHE
 *         <!-- 缓存 -->
 *         <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-cache</artifactId>
 *         </dependency>
 *         <!-- ehcache -->
 *         <dependency>
 *             <groupId>org.ehcache</groupId>
 *             <artifactId>ehcache</artifactId>
 *             <version>3.10.8</version>
 *         </dependency>
 *         <dependency>
 *             <groupId>javax.cache</groupId>
 *             <artifactId>cache-api</artifactId>
 *         </dependency>
 *</pre>
 ***************************/
@Configuration
public class MyEhcacheConfig {


    /**
     * 存磁盘缓存,持久化 CacheManager->dickCache
     * @return
     */
    @Bean
    public Cache<String, String>  persistentCacheManager(){
        PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .with(CacheManagerBuilder.persistence("/opt/cache/token/")) // 缓存目录
                .withCache("dick", CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
                                ResourcePoolsBuilder.newResourcePoolsBuilder()
                                        .disk(1, MemoryUnit.GB, true))
                        .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(4)))
                        .withEvictionAdvisor((key, value) -> false))
                .build(true);
        Cache<String, String> dickCache = persistentCacheManager.getCache("dick", String.class, String.class);
        return dickCache;
    }


    /**
     * 用于本地缓存  eg: @Cacheable(value = "MIN10", keyGenerator = "simpleKeyGenerator")
     * @return
     */
    @Bean
    public CacheManager  cacheManager() {
        // 构建缓存管理器
        CacheManager  cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .withCache("SEC30",getCacheConfigurationWithTtl(Duration.ofSeconds(30)))
                .withCache("MIN5", getCacheConfigurationWithTtl(Duration.ofSeconds(5*60)))
                .withCache("MIN15", getCacheConfigurationWithTtl(Duration.ofSeconds(15*60)))
                .withCache("MIN30", getCacheConfigurationWithTtl(Duration.ofSeconds(30*60)))
                .withCache("MIN60", getCacheConfigurationWithTtl(Duration.ofSeconds(60*60)))
                .withCache("MIN120", getCacheConfigurationWithTtl(Duration.ofSeconds(120*60)))
                .build(true); // 启动缓存管理器
        return  cacheManager;
    }

    /**
     * 优先内存
     * @param duration
     * @return
     */
    private  CacheConfigurationBuilder<String, String> getCacheConfigurationWithTtl(Duration duration){
        CacheConfigurationBuilder<String, String> cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
                        ResourcePoolsBuilder.newResourcePoolsBuilder()
                                .heap(1000, EntryUnit.ENTRIES) // 最大存储1000条记录
                                .offheap(1, MemoryUnit.MB)
                                .disk(500, MemoryUnit.MB, true))
//                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(20)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(duration)) // ttl
//                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(3)))  TTI是指缓存项从最后一次访问到过期的时间间隔。
                .withEvictionAdvisor((key, value) -> false);
        return cacheConfigurationBuilder;
    }

    /**
     * 获取 cache
     * @return
     */
    public Cache<String, String> getCache(String name) {
//        return cacheManager.getCache(name, String.class, String.class);
          return null;
    }

    public void close() {
//        cacheManager.close(); // 关闭缓存管理器
    }


    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                //可以把参数拼接后Md5
                stringBuilder.append( JSON.toJSONString(obj)+"");
            }
            stringBuilder.append("]");
            return stringBuilder.toString();
        };
    }

}