您的位置:首页 > 新闻 > 资讯 > SpringCache之本地缓存

SpringCache之本地缓存

2025/2/28 1:09:33 来源:https://blog.csdn.net/m0_73363097/article/details/142028274  浏览:    关键词:SpringCache之本地缓存

针对不同的缓存技术,需要实现不同的cacheManager,Spring定义了如下的cacheManger实现。

CacheManger

描述

SimpleCacheManager

使用简单的Collection来存储缓存,主要用于测试

ConcurrentMapCacheManager

使用ConcurrentMap作为缓存技术(默认),需要显式的删除缓存,无过期机制

NoOpCacheManager

仅测试用途,不会实际存储缓存

EhCacheCacheManager

使用EhCache作为缓存技术,以前在hibernate的时候经常用

GuavaCacheManager

使用google guava的GuavaCache作为缓存技术(1.5版本已不建议使用)

CaffeineCacheManager

是使用Java8对Guava缓存的重写,spring5(springboot2)开始用Caffeine取代guava

HazelcastCacheManager

使用Hazelcast作为缓存技术

JCacheCacheManager

使用JCache标准的实现作为缓存技术,如Apache Commons JCS

RedisCacheManager

使用Redis作为缓存技术

常规的SpringBoot已经为我们自动配置了EhCache、Collection、Guava、ConcurrentMap等缓存,默认使用ConcurrentMapCacheManager。SpringBoot的application.properties配置文件,使用spring.cache前缀的属性进行配置。

使用

1.添加依赖

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

2.添加配置类

2.1 ConcurrentMapCacheManager,

spring默认就是ConcurrentMapCache,如果不指定缓存名称,可以不加配置类,直接@EnableCaching写道启动类上

@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Bean("ConcurrentMapCacheManager")@Primarypublic CacheManager caffeineCacheManager() {ConcurrentMapCacheManager concurrentMapCacheManager = new ConcurrentMapCacheManager();//可以事先指定chcheName//Collection<String> cacheNames = concurrentMapCacheManager.getCacheNames();//if (CollectionUtils.isEmpty(cacheNames)){//    集合//    concurrentMapCacheManager.setCacheNames();//}return concurrentMapCacheManager;}}

2.2 caffeine

同理,如果不需要特殊参数,加入依赖后也可不写配置类

<!-- 使用  caffeine https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine --><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.6.0</version></dependency>
@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Bean("caffeineCacheManager")@Primarypublic CacheManager caffeineCacheManager() {CaffeineCacheManager cacheManager = new CaffeineCacheManager();// 方案一(常用):定制化缓存CachecacheManager.setCaffeine(Caffeine.newBuilder()// 缓存项在写入后的过期时间为 5 分钟。.expireAfterWrite(5, TimeUnit.MINUTES)//设置缓存的初始容量为 100 个缓存项。.initialCapacity(100)//设置缓存的最大容量为 200 个缓存项。.maximumSize(200));return cacheManager;}
}

3.使用

主要基于Spring缓存注解@Cacheable、@CacheEvict、@CachePut的方式使用

  1. @Cacheable :改注解修饰的方法,若不存在缓存,则执行方法并将结果写入缓存;若存在缓存,则不执行方法,直接返回缓存结果。
  2. @CachePut :执行方法,更新缓存;该注解下的方法始终会被执行。
  3. @CacheEvict :删除缓存

3.1cacheable

调用这个方法的时候,会从缓存中查询,如果没有,查询数据库并将执行的结果存入缓存中,否则返回缓存中的对象。

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个,就是缓存的首个前缀

例如:
@Cacheable(value=”room”)
@Cacheable(value={”room1”,”room2”}

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@Cacheable(value=”room”,key=”#userId”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value=room”,condition=”#userId > 2”)

@Component
public class UserCache {@Cacheable(cacheNames = "room", key = "#userId")public User getUserId(Interger userId){return queryuser();}
}

3.2 CachePut

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

@CachePut(value=room”)

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,也可以使用返回值结果字段result

@CachePut(value=”room”,key=”#userId”)

@CachePut(value=”room”,key=”#result.userId”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CachePut(value=”room”,condition=”#userId>2”)

@Component
public class UserCache {@CachePut(cacheNames = "room", key = "#result.deptId+':'+#userId")public User getUserId(String userId){return queryuser();}}

3.3@CachEvict

主要针对方法配置,能够根据一定的条件对缓存进行清空

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

@CacheEvict(value=”my cache”)

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@CacheEvict(value=”testcache”,key=”#userName”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CacheEvict(value=”testcache”,condition=”#userName.length()>2”)

allEntries

是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存

@CachEvict(value=”testcache”,allEntries=true)

beforeInvocation

是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存

@CachEvict(value=”testcache”,beforeInvocation=true)

@Component
public class UserCache {@CacheEvict(cacheNames = "room")public User getUserId(String userId){return null;}}

3.4 cacheManager的简单使用

//获取缓存
Cache user = cacheManager.getCache("room");
//获取所有缓存数据
User nativeCache = (User)user.getNativeCache();
//获取某个key的数据
Object o1 = user.get("1").get();
//存入数据user.putIfAbsent(Object var1, @Nullable Object var2);user.put(Object var1, @Nullable Object var2);
//清空数据
user.evictIfPresent("room");

spring cache源码

public interface Cache {String getName();Object getNativeCache();@NullableValueWrapper get(Object var1);@Nullable<T> T get(Object var1, @Nullable Class<T> var2);@Nullable<T> T get(Object var1, Callable<T> var2);void put(Object var1, @Nullable Object var2);@Nullabledefault ValueWrapper putIfAbsent(Object key, @Nullable Object value) {ValueWrapper existingValue = this.get(key);if (existingValue == null) {this.put(key, value);}return existingValue;}void evict(Object var1);default boolean evictIfPresent(Object key) {this.evict(key);return false;}void clear();default boolean invalidate() {this.clear();return false;}public static class ValueRetrievalException extends RuntimeException {@Nullableprivate final Object key;public ValueRetrievalException(@Nullable Object key, Callable<?> loader, Throwable ex) {super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);this.key = key;}@Nullablepublic Object getKey() {return this.key;}}@FunctionalInterfacepublic interface ValueWrapper {@NullableObject get();}
}

caffeine扩展的loadingCache

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.github.benmanes.caffeine.cache;import java.util.Map;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;public interface LoadingCache<K, V> extends Cache<K, V> {@Nullable V get(@NonNull K var1);@NonNull Map<@NonNull K, @NonNull V> getAll(@NonNull Iterable<? extends @NonNull K> var1);void refresh(@NonNull K var1);
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com