SpringBoot从文件路径下的META-ING/spring.factories中读入需要配置的类的名称。然后用资源加载器加载注册到IoC容器中,尽心解析注解为Bean Definiton。但是不是所有的都能初始化为Bean,只有满足条件的类才能初始化我Bean。是由一些条件注解来判断的
例如下面的CacehAutoConfiguration
// 这是一个配置类,可以被ConfigurationClassParser解析器进行注解解析
@Configuration(proxyBeanMethods = false)
// 条件注解必须存在CacheManager类
@ConditionalOnClass(CacheManager.class)
// 必须有一个CacheAspectSupport Bean存在在IoC容器中
// 该Bean是由@EnabelCache来加载的,所以要使用Spring Cache就必须对 主引导类标注@EnableCache
@ConditionalOnBean(CacheAspectSupport.class)
// 不存在CacheManeger Bean
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
// 导入CacheManager 这是在满足所有条件对CacheAutoConfiguration进行加载注解的时候才能触发的操作
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
public class CacheAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider<CacheManagerCustomizer<?>> customizers) {
return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
}
@Bean
public CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cacheProperties,
ObjectProvider<CacheManager> cacheManager) {
return new CacheManagerValidator(cacheProperties, cacheManager);
}
@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
@ConditionalOnBean(AbstractEntityManagerFactoryBean.class)
static class CacheManagerEntityManagerFactoryDependsOnPostProcessor
extends EntityManagerFactoryDependsOnPostProcessor {
CacheManagerEntityManagerFactoryDependsOnPostProcessor() {
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() + "')");
}
}
/**
* {@link ImportSelector} to add {@link 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++) {
// 读取org.springframework.boot.autoconfigure.cache.***CacheConfiguration
//
imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
}
return imports;
}
}
}
CacheConfigurationImportSelector会读入下面这些配置类,但是并不是每个配置类都满足条件,所以一般没有引入其他缓存中间件入Redis时,会使用SimpleCacheConfiguration来注册CacheManager。但是在有缓存中间件存在的情况下,由于SimpleCacheConfiguration是在最后面,所以优先使用其他,此时就不会用SimpleCacheConfiguration。这也是为什么在有Redis存在的情况下,会自动使用RedisCacheManager,将Redis作为缓存。
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class SimpleCacheConfiguration {
@Bean
ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties,
CacheManagerCustomizers cacheManagerCustomizers) {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
List<String> cacheNames = cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
}
return cacheManagerCustomizers.customize(cacheManager);
}
}