ConfigurationClassPostProcessor
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口(BeanFactoryPostProcessor的子接口),在applicationContext的refresh过程中,负责解析@Configuration、@ComponentScan、@ComponentScans、@Import、@ImportResource、@Bean、@PropertySource、@PropertySources注解。
处理lite配置类
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(...);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(...);
}
this.registriesPostProcessed.add(registryId);
// 处理配置类
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 遍历所有的BeanDefinition(手动注册的单例不会被处理,即没有注册为BeanDefinition),筛选出未曾处理过的配置类
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
// 如果某个BeanDefinition包含了指定属性,那么就说明这个类已经被处理过,不用筛选出来,代码只是打印了log
} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 判断一个BeanDefinition是否是配置类(配置类有full与lite两种类型,但他们都属于配置类)
// 如果类被@Configuration标记,且proxyBeanMethods属性不为false,那么它是full类型的配置类
// 如果类被@Configuration标记,且proxyBeanMethods属性为false,那么它是lite类型的配置类
// 如果类被@Component、@ComponentScan、@Import、@ImportResource标记,那么它是lite类型的配置类
// 如果类有被@Bean标记的方法,那么它是lite类型的配置类
// 其他情况就不是配置类,可见配置类不一定需要被@Configuration标记
// 如果是配置类,那么就筛选出来
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果没有配置类,那么无需继续处理
if (configCandidates.isEmpty()) {
return;
}
// 对候选配置类进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 可以从单例Bean中获取指定名的BeanNameGenerator来覆盖默认的BeanNameGenerator
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
// 默认AnnotationBeanNameGenerator,以简单类名首字母小写作为beanName
this.componentScanBeanNameGenerator = generator;
// 默认FullyQualifiedAnnotationBeanNameGenerator,以类全名作为beanName
this.importBeanNameGenerator = generator;
}
}
}
// 在没有环境是创建环境
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 用来解析候选配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// candidates保存待处理的配置类,alreadyParsed保存已处理的配置类
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 完成@ComponentScan、@ComponentScans、@PropertySource、@PropertySources、@Import的处理
// 解析@ImportResource、@Bean到ConfigurationClass,但它们没有被处理
parser.parse(candidates);
parser.validate();
// 进一步处理配置类(前面只将@ImportResource、@Bean注解的解析结果存入ConfiurationClass,现在对通过ConfiurationClass来处理这些注解)
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 循环调用ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(...)处理每一个ConfigurationClass
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
// 将待处理的配置类清空(因为他们已被处理)
candidates.clear();
// 将本次循环新增的配置类放入待处理的配置类,循环处理,直到没有新的配置类引入
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while (!candidates.isEmpty());
// 将ImportRegistry以单例形式发布出去
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
// 如果使用了缓存类型的注解解析器(解析注解时进行了缓存,以便提高重复解析的效率),兔死狗烹,清除掉缓存
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}
class ConfigurationClassParser {
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
// 所有的parse(...)方法最终都调用了processConfigurationClass(...)方法来解析配置类
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
} else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
// 推迟处理ImportSelector(及DeferredImportSelector类型的ImportSelector)
this.deferredImportSelectorHandler.process();
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) {
// 通过ConditionEvaluator来忽略配置类的解析
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
...
// 初始化时,SourceClass和ConfigurationClass代表的是同一个类
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// ConfigurationClass代表的是配置类,而SourceClass代表的是处理类
// 该方法返回的SourceClass是刚处理的SourceClass的父类(如果父类包名是以"java"开头的,则返回null)
// 这样可以递归父类处理SourceClass,直到遇到java自己定义的类才放弃递归,整个过程中ConfigurationClass不变
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
} while (sourceClass != null);
// 将解析后的ConfigurationClass缓存起来,这样可以获取
this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) {
// 如果配置类被Component标记,那么会将其所有成员内部类也当做配置类递归调用processConfigurationClass(...)
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
processMemberClasses(configClass, sourceClass, filter);
}
// 完成@PropertySource与PropertySources注解的解析和处理
// 根据注解配置的资源路径将每一个properties资源封装为一个PropertySource并加入Environment
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class, PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
} else {
logger.info(...);
}
}
// 完成@ComponentScan与ComponentScans注解的解析和处理
// 根据配置的包名使用ClassPathBeanDefinitionScanner来进行处理,并对扫描到的新配置类进行递归处理
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
// 如果有@ComponentScan与ComponentScans注解并且没有被Conditional忽略才进行处理
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 循环处理本次扫描到的配置类
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 完成@Import的解析和处理,getImports(...)就是获取@Import导入的所有类
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 解析ImportResource注解,并将解析结果保存到configClass
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 解析方法上的@Bean并将解析结果保存在configClass
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 由于Java8中默认方法的出现,此处会解析sourceClass实现的所有接口中被@Bean标记的方法并保存在configClass
processInterfaces(configClass, sourceClass);
// 返回新的SourceClass就是当前SourceClass的父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
return sourceClass.getSuperClass();
}
}
return null;
}
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
// 循环导入抛错
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
} else {
// 这里就是为了解决循环导入问题,在@Import处理过程前后分别入栈和出栈
this.importStack.push(configClass);
try {
// 依次处理被导入的候选类,不同类型的候选类会有不同的处理方式
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// 如果导入的是ImportSelector类型的处理
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass,
ImportSelector.class, this.environment, this.resourceLoader, this.registry);
// 如果被导入类是DeferredImportSelector类型,那么推迟执行
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
} else {
// 以被导入类对象的selectImports(...)方法返回的类全名数组作为导入类递归调用
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// 如果被导入的是ImportBeanDefinitionRegistrar类型,解析出配置留在ConfigurationClassBeanDefinitionReader中处理
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils.instantiateClass(candidateClass,
ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
} else {
// 如果被导入的不是以上列出的类型,直接把导入的类当做配置类处理(ConfigClass的importBy就是导入它的配置类)
// 被导入的类不会在此处注册为BeanDefinition,但在后面ConfigurationClassBeanDefinitionReader会注册
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
} finally {
this.importStack.pop();
}
}
}
}
class ConfigurationClassBeanDefinitionReader {
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
// 如果应该忽略配置类,那么将其从注册中心删除
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// 如果当前配置类是被导入的,那么根据配置类的注解信息来生成BeanDefinition并注册
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 依次处理所有BeanMethod(被@Bean标记的方法)
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
// 针对每一个BeanMethod创建一个ConfigurationClassBeanDefinition(会使用ConditionEvaluator进行过滤)
// BeanDefinition的factoryMethodName属性设置为当前BeanMethod代表的方法名
// 如果是静态方法就将beanClassName设置为配置类的类全名,否则将factoryBeanName设置为配置类的beanName
// 以@Bean的属性及其他注解(@Scope、@Lazy等)来初始化BeanDefinition的相应字段
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 对于Java程序直接使用XmlBeanDefinitionReader来解析导入的资源(其他语言如groovy使用其他解析器)
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 直接调用所有ImportBeanDefinitionRegistrar的registerBeanDefinitions(...)方法
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
}
处理full配置类
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(...);
}
this.factoriesPostProcessed.add(factoryId);
// 确保先执行了processConfigBeanDefinitions(...)方法
if (!this.registriesPostProcessed.contains(factoryId)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 将所有full配置类的BeanDefinition的类型替换为ConfigurationClassEnhancer创建的代理类
enhanceConfigurationClasses(beanFactory);
// 注册ImportAware感知接口的处理器
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
}