概述
CacheAutoConfiguration
是Spring Boot
关于缓存机制的自动配置。它在开发人员使用了@EnableCaching
注解,引入了底层的缓存实现机制包,底层缓存机制自动配置完成之后才应用。这里的底层缓存机制包指的是redis
,hazelcast
这种Spring Cache
所使用的底层缓存库包。这里的底层缓存机制自动配置指的是RedisAutoConfiguration
,HazelcastAutoConfiguration
这样的自动配置,它们并非仅为Spring Cache
服务,但它们提供的客户端组件bean
会被CacheAutoConfiguration
用于构建Spring Cache
缓存机制上层组件cacheManager
。
CacheAutoConfiguration
的主要效果如下 :
- 导入底层缓存基础设施配置定义
bean cacheManager
可以参考
RedisCacheConfiguration
,HazelcastCacheConfiguration
。 - 定义
bean CacheManagerCustomizers
这是一个容器中所有
CacheManagerCustomizer
的组合bean
,缺省情况下容器中没有CacheManagerCustomizer bean
。
如果开发人员自定义了bean CacheManagerCustomizers
,此处定义不生效。 - 定义
bean CacheManagerValidator cacheAutoConfigurationValidator
该
bean
的目的只是确保CacheAutoConfiguration
应用时bean cacheManager
已经存在,否则抛出异常。 - 定义内部配置类
CacheManagerJpaDependencyConfiguration
该内部配置类同时继承自
EntityManagerFactoryDependsOnPostProcessor
。该内部配置类在Spring Data JPA
环境下生效,
它通过EntityManagerFactoryDependsOnPostProcessor
定义的能力声明容器中所有类型为EntityManagerFactory
的bean
都依赖于bean cacheManager
。
源代码
源代码版本 : spring-boot-autoconfigure-2.1.3.RELEASE
package org.springframework.boot.autoconfigure.cache;
// 省略 import 行
/**
* EnableAutoConfiguration Auto-configuration for the cache abstraction. Creates a
* CacheManager if necessary when caching is enabled via EnableCaching.
*
* Cache store can be auto-detected or specified explicitly via configuration.
*
* @author Stephane Nicoll
* @since 1.3.0
* @see EnableCaching
*/
@Configuration
// 仅在类 CacheManager 存在时生效
@ConditionalOnClass(CacheManager.class)
// 仅在类型为 CacheAspectSupport 的 bean 存在时才生效
// 换句话讲,开发人员使用了 @EnableCaching 时才有效,因为注解 @EnableCaching 隐式导致了
// bean CacheInterceptor cacheInterceptor 的定义,而 CacheInterceptor 实现了接口 CacheAspectSupport
@ConditionalOnBean(CacheAspectSupport.class)
// 仅在类型为 CacheManager , 名称为 cacheResolver 的 bean 不存在时生效
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
// 确保前缀为 spring.cache 的配置项加载到 bean CacheProperties
@EnableConfigurationProperties(CacheProperties.class)
// Spring Cache 自动配置机制必须在缓存数据基础设施自动配置应用之后进行
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
// 导入 CacheConfigurationImportSelector , 其实是导入 Spring Cache 使用的各类基础设置
// 的配置,比如 RedisCacheConfiguration , EhCacheCacheConfiguration , HazelcastCacheConfiguration,
// 这些配置会基于相应基础设施提供 bean cacheManager
@Import(CacheConfigurationImportSelector.class)
public class CacheAutoConfiguration {
// 定义 bean CacheManagerCustomizers cacheManagerCustomizers,
// 基于容器中存在的 CacheManagerCustomizer bean 组件,可能有多个,将它们
// 组合包装为一个类型为 CacheManagerCustomizers 的 bean 组件
// 缺省情况下,容器中没有 CacheManagerCustomizer bean 组件
@Bean
@ConditionalOnMissingBean
public CacheManagerCustomizers cacheManagerCustomizers(
ObjectProvider<CacheManagerCustomizer<?>> customizers) {
return new CacheManagerCustomizers(
customizers.orderedStream().collect(Collectors.toList()));
}
// 定义bean CacheManagerValidator cacheAutoConfigurationValidator,
// 该 bean 存在的意义在于确保容器中存在 bean cacheManager, 从而确保
// 缓存机制可以继续被配置和使用
@Bean
public CacheManagerValidator cacheAutoConfigurationValidator(
CacheProperties cacheProperties, ObjectProvider<CacheManager> cacheManager) {
return new CacheManagerValidator(cacheProperties, cacheManager);
}
// 嵌套配置文件,针对 Spring Data JPA 的缓存配置
// 如果 bean AbstractEntityManagerFactoryBean 存在才生效
// 该配置同时是一个 EntityManagerFactoryDependsOnPostProcessor ,
// 它动态声明了所有类型为 EntityManagerFactory 的 bean 都必须依赖于
// 名称为 cacheManager 的 bean
@Configuration
@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
@ConditionalOnBean(AbstractEntityManagerFactoryBean.class)
protected static class CacheManagerJpaDependencyConfiguration
extends EntityManagerFactoryDependsOnPostProcessor {
public CacheManagerJpaDependencyConfiguration() {
super("cacheManager");
}
}
/**
* Bean used to validate that a CacheManager exists and provide a more meaningful
* exception.
*/
static class CacheManagerValidator implements InitializingBean {
private final CacheProperties cacheProperties;
private final ObjectProvider<CacheManager> cacheManager;
CacheManagerValidator(CacheProperties cacheProperties,
ObjectProvider<CacheManager> cacheManager) {
this.cacheProperties = cacheProperties;
this.cacheManager = cacheManager;
}
@Override
public void afterPropertiesSet() {
Assert.notNull(this.cacheManager.getIfAvailable(),
() -> "No cache manager could "
+ "be auto-configured, check your configuration (caching "
+ "type is '" + this.cacheProperties.getType() + "')");
}
}
/**
* ImportSelector to add CacheType configuration classes.
*/
static class CacheConfigurationImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
CacheType[] types = CacheType.values();
String[] imports = new String[types.length];
for (int i = 0; i < types.length; i++) {
imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
}
return imports;
}
}
}