推荐ehcache 和 Caffeine https://blog.csdn.net/sco5282/article/details/142024324
版本:
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>
import com.alibaba.fastjson.JSON; import org.ehcache.Cache; import org.ehcache.PersistentCacheManager; import org.ehcache.config.CacheConfiguration; 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.ehcache.core.config.DefaultConfiguration; import org.ehcache.jsr107.EhcacheCachingProvider; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.jcache.JCacheCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.PreDestroy; import javax.cache.Caching; import java.time.Duration; import java.util.HashMap; import java.util.Map; /*************************** *<pre> * @Project Name : bk * @Package : 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 @EnableCaching public class MyEhcacheConfig { private final PersistentCacheManager persistentCacheManager; public MyEhcacheConfig() { persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withCache("dickTokenCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .disk(1, MemoryUnit.GB, true)) .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(24))) .withEvictionAdvisor((key, value) -> false)) .with(CacheManagerBuilder.persistence("/opt/cache/token/")) // 缓存目录 .build(true); } /** * 避免出现 ehcache Caused by: java.lang.RuntimeException: Persistence directory already locked */ @PreDestroy public void shutdown() { if (persistentCacheManager != null) { persistentCacheManager.close(); } } /** * 存磁盘缓存,持久化 CacheManager->dickCache * @return */ @Bean("dickTokenCache") public Cache<String, String> dickTokenCache(){ Cache<String, String> dickCache = persistentCacheManager.getCache("dickTokenCache", String.class, String.class); return dickCache; } /** * 用于本地缓存 eg: @Cacheable(value = "MIN10", keyGenerator = "simpleKeyGenerator") * @return */ @Bean public org.springframework.cache.CacheManager jCacheCacheManager() { Map<String, CacheConfiguration<?, ?>> cacheMap = new HashMap<>(); cacheMap.put("SEC30", getCacheConfigurationWithTtl(Duration.ofSeconds(30)).build()); cacheMap.put("MIN5", getCacheConfigurationWithTtl(Duration.ofMillis(5)).build()); EhcacheCachingProvider ehcacheCachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider(EhcacheCachingProvider.class.getName()); DefaultConfiguration defaultConfiguration = new DefaultConfiguration(cacheMap, ehcacheCachingProvider.getDefaultClassLoader()); javax.cache.CacheManager cacheManager = ehcacheCachingProvider.getCacheManager(ehcacheCachingProvider.getDefaultURI(), defaultConfiguration); JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager); return jCacheCacheManager; } /** * 优先内存 * @param duration * @return */ private CacheConfigurationBuilder<String, Object> getCacheConfigurationWithTtl(Duration duration){ CacheConfigurationBuilder<String, Object> cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(1000, EntryUnit.ENTRIES) // 最大存储1000条记录 .offheap(100, MemoryUnit.MB) ) .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(duration)) // ttl Duration.ofSeconds(20) // .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(3))) TTI是指缓存项从最后一次访问到过期的时间间隔。 .withEvictionAdvisor((key, value) -> false); return cacheConfigurationBuilder; } @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(); }; } }