4.springboot-redis spring cache上篇

1.spring cache简介

  • spring对各种缓存技术进行了封装(包括concurrentMap,redis,guava,caffeine,jCache,ehCache等等),并提供一致的对外接口;
  • 包括CacheManager和Cache两个接口,Cache接口包含缓存的各种操作,CacheManager接口则负责管理Cache;
    • CacheManager会持有多个Cache实例的引用,根据name区分;
    • Cache接口包含一些简单的缓存操作,功能没有redisTemplate强大;
  • 可使用代码调用,也可使用注解,使用注解更为方便;
    • 代码:cacheManager.getCache(“test”).put(“key”, “value”);
    • 注解:(转)注解示例

2.spring cache结构

4.springboot-redis spring cache上篇_第1张图片

3.spring cache解析

3.1.cache和cacheManager接口

  • cache接口包含缓存的各种操作,CacheManager接口持有cache接口实例,并负责管理Cache;
public interface Cache {

	//**获取cache的名称
	String getName();

	//**获取底层真正使用的缓存(concurrentMap,redis)
	Object getNativeCache();

	//**根据key获取value,ValueWrapper是一个函数式接口,可自定义实现定义value的转换操作
	ValueWrapper get(Object key);

	//**根据key获取value,并把value转换为type类型
	 T get(Object key, @Nullable Class type);

	//**根据key获取value,Callable任务计算value
	 T get(Object key, Callable valueLoader);

	//**保存键值对
	void put(Object key, @Nullable Object value);

	//**如果键值对不存在则保存并返回null,存在则返回已存在的value
	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;
	}

	//**缓存value的包装器
	@FunctionalInterface
	interface ValueWrapper {
        
        //**标记返回值可为空,大部分ide可支持编译期检查
		@Nullable
		Object get();
	}
}
public interface CacheManager {

	//**根据name获取CacheManager管理的Cache
	Cache getCache(String name);

	//**获取CacheManager管理的所有Cache的名称
	Collection getCacheNames();

}

3.2.AbstractValueAdaptingCache

  • 保存的value为null时,如果allowNullValues=true,则保存NullValue,如果allowNullValues=false,则抛出异常。默认为true;
  • 读取的value为NullValue时,返回null,不受allowNullValues影响;
  • lookup方法直接从底层存储获取value,不会进行任何处理和转换,其它方法会对value进行一些处理;
//**抽象类,对value进行一行处理
public abstract class AbstractValueAdaptingCache implements Cache {
    //**是否允许空值
	private final boolean allowNullValues;

    //**获取value,然后转换为ValueWrapper
	public ValueWrapper get(Object key) {
		Object value = lookup(key);
		return toValueWrapper(value);
	}

	//**获取value,并强制转换为type类型
	public  T get(Object key, @Nullable Class type) {
		Object value = fromStoreValue(lookup(key));
		if (value != null && type != null && !type.isInstance(value)) {
			throw new IllegalStateException(
					"Cached value is not of required type [" + type.getName() + "]: " + value);
		}
		return (T) value;
	}

	//**获取value,不进行任务其它处理和转换
	protected abstract Object lookup(Object key);

    //**获取value时进行空值处理
	protected Object fromStoreValue(@Nullable Object storeValue) {
		if (this.allowNullValues && storeValue == NullValue.INSTANCE) {
			return null;
		}
		return storeValue;
	}

	//**保存value时进行空值处理
	protected Object toStoreValue(@Nullable Object userValue) {
		if (userValue == null) {
			if (this.allowNullValues) {
				return NullValue.INSTANCE;
			}
			throw new IllegalArgumentException(
					"Cache '" + getName() + "' is configured to not allow null values but null was provided");
		}
		return userValue;
	}

	//**把value转换为SimpleValueWrapper
	protected Cache.ValueWrapper toValueWrapper(@Nullable Object storeValue) {
		return (storeValue != null ? new SimpleValueWrapper(fromStoreValue(storeValue)) : null);
	}
}

3.3.ConcurrentMapCache和ConcurrentMapCacheManager

  • ConcurrentMapCache使用ConcurrentMap作为缓存的存储;
  • ConcurrentMapCacheManager使用ConcurrentMap保存name和ConcurrentMapCache的键值对;
  • ConcurrentMapCache是AbstractValueAdaptingCache的子类,继承了AbstractValueAdaptingCache对空值的处理方式;
  • 如果SerializationDelegate!=null,则会对value进行序列化,为null则直接保存value对象。默认为null;
    • SerializationDelegate使用了delegate委派模式:
      • 类B和类A是两个互相没有任何关系的类,但是B有和A一样的方法和属性;
      • B中的方法/属性直接调用A中同名的方法和属性;
    • delegate委派和proxy代理的区别:
      • 委派:类B和类A没有任何关系;
      • 代理:类B和类A需要实现同一个接口;
public class ConcurrentMapCache extends AbstractValueAdaptingCache {
    //*cache的name
	private final String name;
    //**cache底层使用的存储
	private final ConcurrentMap store;

	//**序列化工具(delegate委派模式)
	private final SerializationDelegate serialization;

	//**获取value,不进行任务其它处理和转换
	protected Object lookup(Object key) {
		return this.store.get(key);
	}

	//**获取value,有则返回,没有则调用传入的Callable获取值,并保存到缓存中
	public  T get(Object key, Callable valueLoader) {
		return (T) fromStoreValue(this.store.computeIfAbsent(key, k -> {
			try {
				return toStoreValue(valueLoader.call());
			}
			catch (Throwable ex) {
				throw new ValueRetrievalException(key, valueLoader, ex);
			}
		}));
	}

	//**保存value
	public void put(Object key, @Nullable Object value) {
		this.store.put(key, toStoreValue(value));
	}

	//**键值对不存在则保存,并把当前缓存中的value转换SimpleValueWrapper为后返回
	public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
		Object existing = this.store.putIfAbsent(key, toStoreValue(value));
		return toValueWrapper(existing);
	}

	//**删除键值对
	public void evict(Object key) {
		this.store.remove(key);
	}

	//**删除键值对,并返回键值对是否存在
	public boolean evictIfPresent(Object key) {
		return (this.store.remove(key) != null);
	}

	//**删除所有键值对
	public void clear() {
		this.store.clear();
	}

	//**删除键值对,并返回是否存在键值对
	public boolean invalidate() {
		boolean notEmpty = !this.store.isEmpty();
		this.store.clear();
		return notEmpty;
	}

	//**保存value时进行空值处理,对并对value进行序列化
	protected Object toStoreValue(@Nullable Object userValue) {
		Object storeValue = super.toStoreValue(userValue);
		if (this.serialization != null) {
			try {
				return serializeValue(this.serialization, storeValue);
			}
			catch (Throwable ex) {
				throw new IllegalArgumentException("Failed to serialize cache value '" + userValue +
						"'. Does it implement Serializable?", ex);
			}
		}
		else {
			return storeValue;
		}
	}

    //**调用SerializationDelegate对value进行序列化
	private Object serializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			serialization.serialize(storeValue, out);
			return out.toByteArray();
		}
		finally {
			out.close();
		}
	}

	//**获取value时进行空值处理,对并对value进行反序列化
	protected Object fromStoreValue(@Nullable Object storeValue) {
		if (storeValue != null && this.serialization != null) {
			try {
				return super.fromStoreValue(deserializeValue(this.serialization, storeValue));
			}
			catch (Throwable ex) {
				throw new IllegalArgumentException("Failed to deserialize cache value '" + storeValue + "'", ex);
			}
		}
		else {
			return super.fromStoreValue(storeValue);
		}

	}

    //**调用SerializationDelegate对value进行反序列化
	private Object deserializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
		ByteArrayInputStream in = new ByteArrayInputStream((byte[]) storeValue);
		try {
			return serialization.deserialize(in);
		}
		finally {
			in.close();
		}
	}

}
  • Aware接口,一个标记,标记在spring容器初始化时需要获取上下文中当前的一些运行环境,如BeanFactoryAware,ApplicationContextAware等;
  • BeanClassLoaderAware,获取当前的ClassLoader;
  • 如果初始化时创建了缓存,则后续只能使用初始化的缓存,不能创建新缓存;
  • 如果初始化时没有创建缓存,则后续使用时动态的创建新缓存;
  • 保存value时,如果storeByValue=false,会对value进行序列化,为true则直接保存value,默认为false;
public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderAware {
    //**使用ConcurrentMap保存和管理ConcurrentMapCache
	private final ConcurrentMap cacheMap = new ConcurrentHashMap<>(16);
    //**是否允许动态的创建ConcurrentMapCache
	private boolean dynamic = true;
    //**是否允许空值
	private boolean allowNullValues = true;
    //**保存value时是否允许对value进行序列化
	private boolean storeByValue = false;
    //**序列化器
	private SerializationDelegate serialization;
	
	//**默认构造方法,不创建任何缓存,当获取缓存时,如果不存在,则创建新的缓存
	public ConcurrentMapCacheManager() {
	}

    //**根据传入的cache name创建多个ConcurrentMapCache,后续则不能在创建新的缓存
	public void setCacheNames(@Nullable Collection cacheNames) {
		if (cacheNames != null) {
			for (String name : cacheNames) {
				this.cacheMap.put(name, createConcurrentMapCache(name));
			}
			this.dynamic = false;
		}
		else {
			this.dynamic = true;
		}
	}

	//**设置是否允许空值,对所有缓存有效
	public void setAllowNullValues(boolean allowNullValues) {
		if (allowNullValues != this.allowNullValues) {
			this.allowNullValues = allowNullValues;
			// Need to recreate all Cache instances with the new null-value configuration...
			recreateCaches();
		}
	}

	//**设置是否允许对value进行序列化,对所有缓存有效
	public void setStoreByValue(boolean storeByValue) {
		if (storeByValue != this.storeByValue) {
			this.storeByValue = storeByValue;
			// Need to recreate all Cache instances with the new store-by-value configuration...
			recreateCaches();
		}
	}

	//**继承自BeanClassLoaderAware,根据注入的ClassLoader创建序列化器(使用java序列化和反序列化)
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.serialization = new SerializationDelegate(classLoader);
		// Need to recreate all Cache instances with new ClassLoader in store-by-value mode...
		if (isStoreByValue()) {
			recreateCaches();
		}
	}

    //**获取所有的cache name,返回一个不可变的set
	public Collection getCacheNames() {
		return Collections.unmodifiableSet(this.cacheMap.keySet());
	}

	//**根据name获取cache,如果cache不存在且dynamic=true,则根据name创建一个cache,并保存到cacheMap中(线程安全的)
	public Cache getCache(String name) {
		Cache cache = this.cacheMap.get(name);
		if (cache == null && this.dynamic) {
			synchronized (this.cacheMap) {
				cache = this.cacheMap.get(name);
				if (cache == null) {
					cache = createConcurrentMapCache(name);
					this.cacheMap.put(name, cache);
				}
			}
		}
		return cache;
	}

    //**根据当前的name,重新创建新的cache
	private void recreateCaches() {
		for (Map.Entry entry : this.cacheMap.entrySet()) {
			entry.setValue(createConcurrentMapCache(entry.getKey()));
		}
	}

	//**根据name创建新的ConcurrentMapCache
	protected Cache createConcurrentMapCache(String name) {
		SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
		return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),
				isAllowNullValues(), actualSerialization);

	}
}

3.4.TransactionAwareCacheDecorator和TransactionAwareCacheManagerProxy

  • TransactionAwareCacheDecorator使用了decorator装饰器模式;
  • TransactionAwareCacheManagerProxy使用了proxy代理模式;
    • 装饰器模式和代理模式的区别:
      • 装饰器:关注于在一个对象上动态的添加方法;通常在装饰器的构造方法中,需要传入装饰的类的实例,实例化后通常不允许修改装饰的类;
      • 代理:关注于控制对对象的访问;通常由代理类自己创建代理类的实例,调用时由代理类判断应该调用哪个实例的方法;
  • 本身并没有缓存功能,作用是扩展普通的cache和cacheManager,使其支持事务;
public class TransactionAwareCacheDecorator implements Cache {
    //**装饰的类,实例化后不允许修改
	private final Cache targetCache;

	//**保存value时,判断是否存在事务,存在事务则在事务提交之后保存value
	public void put(final Object key, @Nullable final Object value) {
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
				@Override
				public void afterCommit() {
					TransactionAwareCacheDecorator.this.targetCache.put(key, value);
				}
			});
		}
		else {
			this.targetCache.put(key, value);
		}
	}


	//**删除键值对时,判断是否存在事务,存在事务则在事务提交之后删除键值对
	public void evict(final Object key) {
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
				@Override
				public void afterCommit() {
					TransactionAwareCacheDecorator.this.targetCache.evict(key);
				}
			});
		}
		else {
			this.targetCache.evict(key);
		}
	}

	//**清除所有键值对时,判断是否存在事务,存在事务则在事务提交之后清除所有键值对
	public void clear() {
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
				@Override
				public void afterCommit() {
					targetCache.clear();
				}
			});
		}
		else {
			this.targetCache.clear();
		}
	}
}
  • InitializingBean接口,spring容器启用时,会调用afterPropertiesSet方法进行一些初始化,同类型还有 @PostConstruct;
public class TransactionAwareCacheManagerProxy implements CacheManager, InitializingBean {
    //**代理的cacheManager,后续可通用set方法修改代理的cacheManager
	private CacheManager targetCacheManager;

	//**根据name获取cache时,对cache进行装饰,以支持事务
	public Cache getCache(String name) {
		Assert.state(this.targetCacheManager != null, "No target CacheManager set");
		Cache targetCache = this.targetCacheManager.getCache(name);
		return (targetCache != null ? new TransactionAwareCacheDecorator(targetCache) : null);
	}
}

3.5.AbstractCacheManager和AbstractTransactionSupportingCacheManager

public abstract class AbstractCacheManager implements CacheManager, InitializingBean {
    //**使用ConcurrentMap保存和管理ConcurrentMapCache
	private final ConcurrentMap cacheMap = new ConcurrentHashMap<>(16);
    //**使用Set保存所有的cache name
	private volatile Set cacheNames = Collections.emptySet();

    //**创建时初始化缓存
	@Override
	public void afterPropertiesSet() {
		initializeCaches();
	}

	//**初始化缓存,并把缓存的name保存到cacheNames中
	public void initializeCaches() {
		Collection caches = loadCaches();

		synchronized (this.cacheMap) {
			this.cacheNames = Collections.emptySet();
			this.cacheMap.clear();
			Set cacheNames = new LinkedHashSet<>(caches.size());
			for (Cache cache : caches) {
				String name = cache.getName();
				this.cacheMap.put(name, decorateCache(cache));
				cacheNames.add(name);
			}
			this.cacheNames = Collections.unmodifiableSet(cacheNames);
		}
	}

	//**加载cache
	protected abstract Collection loadCaches();

    //**根据名称获取cache
	public Cache getCache(String name) {
		//**如果cache存在则直接返回
		Cache cache = this.cacheMap.get(name);
		if (cache != null) {
			return cache;
		}

		//**不存在,调用getMissingCache获取cache
		Cache missingCache = getMissingCache(name);
		if (missingCache != null) {
			//**如果getMissingCache返回的cache不存在,则对cache进行装饰,并保存
			synchronized (this.cacheMap) {
				cache = this.cacheMap.get(name);
				if (cache == null) {
					cache = decorateCache(missingCache);
					this.cacheMap.put(name, cache);
					updateCacheNames(name);
				}
			}
		}
		return cache;
	}

    //**添加缓存
	protected final void addCache(Cache cache) {
		String name = cache.getName();
		synchronized (this.cacheMap) {
			if (this.cacheMap.put(name, decorateCache(cache)) == null) {
				updateCacheNames(name);
			}
		}
	}

	//**对cache进行装饰
	protected Cache decorateCache(Cache cache) {
		return cache;
	}

	//**如果name对应的cache不存在时,如何获取cache
	protected Cache getMissingCache(String name) {
		return null;
	}
}
  • transactionAware=true,则使用TransactionAwareCacheDecorator装饰cache,以支持事务,如果为false,则不会装饰cache。默认false;
public abstract class AbstractTransactionSupportingCacheManager extends AbstractCacheManager {
    //**是否支持事务
	private boolean transactionAware = false;

	//**如果需要支持事务,则使用TransactionAwareCacheDecorator装饰cache,以支持事务
	protected Cache decorateCache(Cache cache) {
		return (isTransactionAware() ? new TransactionAwareCacheDecorator(cache) : cache);
	}
}

你可能感兴趣的:(#,spring,cache)