7、配置类解析
for (String beanName : candidateNames) { // 获取BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 判断这个BeanDefinition的configurationClass属性是不是full或者lite,如果是认为已经处理过了,第一次时默认为空,
// 走下面分支
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
// 打印日志记录下
} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 1) 下面先分析下这个checkConfigurationClassCandidate方法
// 构造一个BeanDefinitionHolder,放入configCandidates中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
// 我们传进来的registry是这个子类
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
// 这边默认值false,所以会进去
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
// 默认是null
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
// 前面已经创建过这个环境了,不为null
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
// 配置类解析工具
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 待处理集合
Set<beandefinitionholder> candidates = new LinkedHashSet<>(configCandidates);
// 已处理集合
Set<configurationclass> alreadyParsed = new HashSet<>(configCandidates.size());
// 循环处理直到candidates.isEmpty()
do {
// 这边开始解析,单独放到第二节分析
parser.parse(candidates);
parser.validate();
Set<configurationclass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor,
this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());
}
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());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
// 清空缓存
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it"ll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory);public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef,
MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
// 获取下类名,如果类名为空或者该类为工厂类
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
// 获取类的元数据信息
AnnotationMetadata metadata;
// 上图的7个candidateNames中只有一个springbootApplication是AnnotatedBeanDefinition,其余全返回false
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
// springbootApplication走到这里
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can"t even load the class file for this Class.
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
metadata = new StandardAnnotationMetadata(beanClass, true);
}
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
// 读取类的元数据信息,这里面包括注解等信息
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
return false;
}
}
// metadata.isAnnotated(Configuration.class.getName()),这个就是判断类上面有没有@Configuration注解
if (isFullConfigurationCandidate(metadata)) {
// 如果true的话设置下这个属性,那么就标记为处理过了
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
} else if (isLiteConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
// 其余6个返回false
return false;
}
// It"s a full or lite configuration candidate... Let"s determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
// 获取下类上的@Order信息
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) { // Do not consider an interface or an annotation...
if (metadata.isInterface()) {
return false;
}
// Any of the typical annotations found?
for (String indicator : candidateIndicators) {
// 判断下类上面有没有这几个注解
if (metadata.isAnnotated(indicator)) {
return true;
}
}
// Finally, let"s look for @Bean methods...
try {
// 判断有没有@Bean的方法
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
return false;
}
}
private static final Set<string> candidateIndicators = new HashSet<>8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
1.2、执行逻辑解析
// do {
// 这边开始解析,单独放到第二节分析
parser.parse(candidates);
parser.validate();
Set<configurationclass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor,
this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());
}
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());
以上是 7、配置类解析 的全部内容, 来源链接: utcz.com/z/513571.html