Spring系列之缓存Cache

Spring Cache

介绍

Spring Cachespring3.1引入的基于注解的一个缓存技术,它是对缓存的一个抽象,有自己的缓存实现方案,在spring-context包下面org.springframework.cache包里面。

缓存实现体系

  • spring-context

    提供了对SpringCache的实现:ConcurrentMapCache

  • spring-boot-starter-cache

    实际上是引入了spring-context-support包,spring只是用这些缓存去实现了Cache接口,具体的实现还是要引入对应的缓存框架的jar包。

    CaffeineCache:com.github.ben-manes.caffeine

    EhCacheCache:net.sf.ehcache

    JCacheCache:javax.cache.cache-api

Cache

Cache介绍

定义了缓存操作的公共接口。

Cache源码

/**
 * 定义了公共缓存操作接口
 */
public interface Cache {

	/**
	 * 返回缓存名称
	 */
	String getName();

	/**
	 * 返回基础原生缓存提供者
	 */
	Object getNativeCache();

	/**
	 * 返回此缓存映射中指定key的值
	 * 如果缓存中没有该键的值,则返回null
	 */
	@Nullable
	ValueWrapper get(Object key);

	/**
	 * 返回此缓存映射中指定key的值
	 * 返回的值会被转换成特定的类型
	 */
	@Nullable
	<T> T get(Object key, @Nullable Class<T> type);

	/**
	 * 返回此缓存映射中指定key的值,获取这个值从Callable是必须的。这个方法提供了简单替换的传统模式“如果	  * 有缓存则返回;否则创建一个缓存然后返回”
	 * 如果可以,实现类应该确保使用这个方法是同步的以至于特定的Callable在同一个key上只能被调用一次
	 */
	@Nullable
	<T> T get(Object key, Callable<T> valueLoader);

	/**
	 * 在缓存中关联一个指定的值和指定的键,如果缓存以前包含了这个键的映射,那么旧的值将被这个指定的值替换
	 * 实际注册可以在异步或延迟模式下执行,后续的查找可能还没有看到值,事务性缓存装饰器可能就是这种情况
	 */
	void put(Object key, @Nullable Object value);

	/**
	 * 将指定的值与缓存中指定的键原子性关联,如果没有关联过。 
	 * 这个等价于:
	 * ValueWrapper existingValue = cache.get(key);
	 * if (existingValue == null) {
	 *     cache.put(key, value);
	 * }
	 * return existingValue;
	 */
	@Nullable
	default ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
		ValueWrapper existingValue = get(key);
		if (existingValue == null) {
			put(key, value);
		}
		return existingValue;
	}

	/**
	 * 如果该缓存中存在改键的映射就删除他,实际上删除可能是异步或者延迟执行的,后续仍然可能看到这个映射存	 * 在, 事务性缓存装饰器可能就是这种情况
	 */
	void evict(Object key);

	/**
	 * 如果该缓存中存在该键的映射就立即删除他,并且在后续的查找中不会存在。
	 */
	default boolean evictIfPresent(Object key) {
		evict(key);
		return false;
	}

	/**
	 * 清理缓存的所有映射,实际上清理可能是异步或者延迟的,后续的查仍然可能看到这个映射
	 */
	void clear();

	/**
	 * 通过删除所有映射使缓存无效,所有映射条目在后续查找时立即不可见。
	 */
	default boolean invalidate() {
		clear();
		return false;
	}

	/**
	 * 一个包装对象表示一个缓存值
	 */
	@FunctionalInterface
	interface ValueWrapper {

		/**
		 * 返回一个实际的值在缓存中。
		 */
		@Nullable
		Object get();
	}

	/**
	 * 包装类异常
	 */
	@SuppressWarnings("serial")
	class ValueRetrievalException extends RuntimeException {
		@Nullable
		private 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;
		}

		@Nullable
		public Object getKey() {
			return this.key;
		}
	}
}

CacheManager

CacheManager介绍

Spring中央缓存管理器SPI

CacheManger源码

/**
 * Spring中央缓存管理器SPI
 */
public interface CacheManager {

	/**
	 * 获取名字关联的缓存,如果原生提供支持缓存可能再运行的时候懒加载
	 */
	@Nullable
	Cache getCache(String name);

	/**
	 * 获取缓存名称的集合
	 */
	Collection<String> getCacheNames();
}

缓存框架

本地缓存

  • Caffeine

Caffeine是使用Java8Guava缓存的重写版本,在Spring Boot 2.0中将取代Guava,基于LRU算法实现,支持多种缓存过期策略。

  • ehcache

​ 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的 CacheProvider

  • GuavaCache

Google Guava工具包中的一个非常方便易用的本地化缓存实现,基于LRU算法实现,支持多种缓存过期策略。

分布式缓存

  • redis

  • memcached

  • Gemfire

组合缓存

  • jetcache

使用本地和远程缓存:本地可以用caffeineLinkedhashmap,远程可以使用redis

你可能感兴趣的:(spring,spring,boot,java)