SpringBoot源码解析(1.3.4)-自动装配原理(@SpringBootApplication注解启动类具体解析过程ConfigurationClassParser.parse)
承接上文 :https://blog.csdn.net/sql2008help/article/details/123354118
ConfigurationClassParser 实例是在org.springframework.context.annotation.ConfigurationClassPostProcessor processConfigBeanDefinitions 方法中创建的,通过 ConfigurationClassParser parse方法解析包含**@SpringBootApplication** 注解的启动类。
class ConfigurationClassParser {
private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new DefaultPropertySourceFactory();
private static final Predicate<String> DEFAULT_EXCLUSION_FILTER = (className) -> {
return className.startsWith("java.lang.annotation.") || className.startsWith("org.springframework.stereotype.");
};
private static final Comparator<ConfigurationClassParser.DeferredImportSelectorHolder> DEFERRED_IMPORT_COMPARATOR = (o1, o2) -> {
return AnnotationAwareOrderComparator.INSTANCE.compare(o1.getImportSelector(), o2.getImportSelector());
};
private final Log logger = LogFactory.getLog(this.getClass());
private final MetadataReaderFactory metadataReaderFactory;
private final ProblemReporter problemReporter;
private final Environment environment;
private final ResourceLoader resourceLoader;
private final BeanDefinitionRegistry registry;
private final ComponentScanAnnotationParser componentScanParser;
private final ConditionEvaluator conditionEvaluator;
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap();
private final Map<String, ConfigurationClass> knownSuperclasses = new HashMap();
private final List<String> propertySourceNames = new ArrayList();
private final ConfigurationClassParser.ImportStack importStack = new ConfigurationClassParser.ImportStack();
// 对 @Import 配置的进行处理
private final ConfigurationClassParser.DeferredImportSelectorHandler deferredImportSelectorHandler = new ConfigurationClassParser.DeferredImportSelectorHandler();
private final ConfigurationClassParser.SourceClass objectSourceClass = new ConfigurationClassParser.SourceClass(Object.class);
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader, BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
this.componentScanParser = new ComponentScanAnnotationParser(environment, resourceLoader, componentScanBeanNameGenerator, registry);
this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
}
parse 方法:
configCandidates 参数表示包含@SpringBootApplication注解的启动类bean定义集合
public void parse(Set<BeanDefinitionHolder> configCandidates) {
Iterator var2 = configCandidates.iterator();
while(var2.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
BeanDefinition bd = holder.getBeanDefinition();
try {
// 不同的bean定义类型执行不同的parse 方法
if (bd instanceof AnnotatedBeanDefinition) {
this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
} else {
this.parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
}
}
// 重点方法,ConfigurationClassParser.DeferredImportSelectorHandler 类方法
this.deferredImportSelectorHandler.process();
}
继续跟踪
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
this.processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
processConfigurationClass 方法:
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
if (!this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
。。。 省略 。。。
ConfigurationClassParser.SourceClass sourceClass = this.asSourceClass(configClass, filter);
do {
sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
} while(sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
}
protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter) throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
this.processMemberClasses(configClass, sourceClass, filter);
}
Iterator var4 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();
AnnotationAttributes importResource;
while(var4.hasNext()) {
importResource = (AnnotationAttributes)var4.next();
if (this.environment instanceof ConfigurableEnvironment) {
this.processPropertySource(importResource);
} else {
this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
}
}
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Iterator var14 = componentScans.iterator();
while(var14.hasNext()) {
AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
Iterator var8 = scannedBeanDefinitions.iterator();
while(var8.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
this.parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 获取 @Import 注解的value值
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
String[] var20 = resources;
int var22 = resources.length;
for(int var23 = 0; var23 < var22; ++var23) {
String resource = var20[var23];
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
Iterator var18 = beanMethods.iterator();
while(var18.hasNext()) {
MethodMetadata methodMetadata = (MethodMetadata)var18.next();
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
this.processInterfaces(configClass, 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;
}
this.getImports(sourceClass) 方法:
获取 @Import 注解的value值,如下图所示:
org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
@SpringBootApplication 注解定义:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@EnableAutoConfiguration 注解定义:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@Import 注解定义:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
processImports 方法:
对 getImports 返回的结果进行处理
private void processImports(ConfigurationClass configClass, ConfigurationClassParser.SourceClass currentSourceClass, Collection<ConfigurationClassParser.SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {
if (!importCandidates.isEmpty()) {
if (checkForCircularImports && this.isChainedImportOnStack(configClass)) {
this.problemReporter.error(new ConfigurationClassParser.CircularImportProblem(configClass, this.importStack));
} else {
this.importStack.push(configClass);
try {
Iterator var6 = importCandidates.iterator();
while(var6.hasNext()) {
ConfigurationClassParser.SourceClass candidate = (ConfigurationClassParser.SourceClass)var6.next();
Class candidateClass;
// 判断当前类是否为 ImportSelector 类型
if (candidate.isAssignable(ImportSelector.class)) {
candidateClass = candidate.loadClass();
ImportSelector selector = (ImportSelector)ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
// org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
// 进入此逻辑
if (selector instanceof DeferredImportSelector) {
// 填充deferredImportSelectorHandler deferredImportSelectors 属性,可以看下图
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector)selector);
} else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<ConfigurationClassParser.SourceClass> importSourceClasses = this.asSourceClasses(importClassNames, exclusionFilter);
this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
// org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar
// 进入此逻辑
} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
candidateClass = candidate.loadClass();
// 实例化 org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar
ImportBeanDefinitionRegistrar registrar = (ImportBeanDefinitionRegistrar)ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
} else {
// 在未解析到 其他 AutoConfiguration 类时程序不会进入此逻辑
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
} catch (BeanDefinitionStoreException var17) {
throw var17;
} catch (Throwable var18) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", var18);
} finally {
this.importStack.pop();
}
}
}
}
ConfigurationClassParser.DeferredImportSelectorHandler ConfigurationClassParser 内部类 DeferredImportSelectorHandler :
private class DeferredImportSelectorHandler {
@Nullable
private List<ConfigurationClassParser.DeferredImportSelectorHolder> deferredImportSelectors;
private DeferredImportSelectorHandler() {
this.deferredImportSelectors = new ArrayList();
}
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
ConfigurationClassParser.DeferredImportSelectorHolder holder = new ConfigurationClassParser.DeferredImportSelectorHolder(configClass, importSelector);
if (this.deferredImportSelectors == null) {
ConfigurationClassParser.DeferredImportSelectorGroupingHandler handler = ConfigurationClassParser.this.new DeferredImportSelectorGroupingHandler();
handler.register(holder);
handler.processGroupImports();
} else {
this.deferredImportSelectors.add(holder);
}
}
public void process() {
List<ConfigurationClassParser.DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
ConfigurationClassParser.DeferredImportSelectorGroupingHandler handler = ConfigurationClassParser.this.new DeferredImportSelectorGroupingHandler();
deferredImports.sort(ConfigurationClassParser.DEFERRED_IMPORT_COMPARATOR);
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
} finally {
this.deferredImportSelectors = new ArrayList();
}
}
}
ConfigurationClassParser.DeferredImportSelectorGroupingHandler ConfigurationClassParser 内部类 DeferredImportSelectorGroupingHandler :
private class DeferredImportSelectorGroupingHandler {
private final Map<Object, ConfigurationClassParser.DeferredImportSelectorGrouping> groupings;
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses;
private DeferredImportSelectorGroupingHandler() {
this.groupings = new LinkedHashMap();
this.configurationClasses = new HashMap();
}
public void register(ConfigurationClassParser.DeferredImportSelectorHolder deferredImport) {
// 这里的group是指 org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup.class
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
ConfigurationClassParser.DeferredImportSelectorGrouping grouping = (ConfigurationClassParser.DeferredImportSelectorGrouping)this.groupings.computeIfAbsent(group != null ? group : deferredImport, (key) -> {
return new ConfigurationClassParser.DeferredImportSelectorGrouping(this.createGroup(group));
});
grouping.add(deferredImport);
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getConfigurationClass());
}
public void processGroupImports() {
Iterator var1 = this.groupings.values().iterator();
while(var1.hasNext()) {
ConfigurationClassParser.DeferredImportSelectorGrouping grouping = (ConfigurationClassParser.DeferredImportSelectorGrouping)var1.next();
Predicate<String> exclusionFilter = grouping.getCandidateFilter();
// 根据 AutoConfigurationImportSelector.AutoConfigurationGroup
// 返回的 自动装配类 Entry 集合 Iterable<Entry>,
// 依次 调用 processImports 方法 往
// org.springframework.context.annotation.ConfigurationClassParser 的
// Map<ConfigurationClass, ConfigurationClass> configurationClasses 属性填充值
grouping.getImports().forEach((entry) -> {
ConfigurationClass configurationClass = (ConfigurationClass)this.configurationClasses.get(entry.getMetadata());
try {
ConfigurationClassParser.this.processImports(configurationClass, ConfigurationClassParser.this.asSourceClass(configurationClass, exclusionFilter), Collections.singleton(ConfigurationClassParser.this.asSourceClass(entry.getImportClassName(), exclusionFilter)), exclusionFilter, false);
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (Throwable var6) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configurationClass.getMetadata().getClassName() + "]", var6);
}
});
}
}
private Group createGroup(@Nullable Class<? extends Group> type) {
Class<? extends Group> effectiveType = type != null ? type : ConfigurationClassParser.DefaultDeferredImportSelectorGroup.class;
return (Group)ParserStrategyUtils.instantiateClass(effectiveType, Group.class, ConfigurationClassParser.this.environment, ConfigurationClassParser.this.resourceLoader, ConfigurationClassParser.this.registry);
}
}
执行完 processImports 方法后,ConfigurationClassPostProcessor 对象属性变化如下,此时只是填充 ConfigurationClassPostProcessor :
this.deferredImportSelectorHandler.process() 方法:
代码如上所示, 其中 processGroupImports 为重点方法,
ConfigurationClassParser.DeferredImportSelectorGrouping ConfigurationClassParser 内部类 DeferredImportSelectorGrouping :
private static class DeferredImportSelectorGrouping {
private final Group group;
private final List<ConfigurationClassParser.DeferredImportSelectorHolder> deferredImports = new ArrayList();
DeferredImportSelectorGrouping(Group group) {
this.group = group;
}
public void add(ConfigurationClassParser.DeferredImportSelectorHolder deferredImport) {
this.deferredImports.add(deferredImport);
}
public Iterable<Entry> getImports() {
Iterator var1 = this.deferredImports.iterator();
while(var1.hasNext()) {
ConfigurationClassParser.DeferredImportSelectorHolder deferredImport = (ConfigurationClassParser.DeferredImportSelectorHolder)var1.next();
// 这里实际调用 org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup process 方法
this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector());
}
// 调用 AutoConfigurationImportSelector.AutoConfigurationGroup 方法返回 自动装配类的Entry 集合
return this.group.selectImports();
}
}
AutoConfigurationImportSelector.AutoConfigurationGroup :
private static class AutoConfigurationGroup implements Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
private final Map<String, AnnotationMetadata> entries = new LinkedHashMap();
private final List<AutoConfigurationImportSelector.AutoConfigurationEntry> autoConfigurationEntries = new ArrayList();
private ClassLoader beanClassLoader;
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private AutoConfigurationMetadata autoConfigurationMetadata;
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> {
return String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName());
});
// 这里开始找到自动配置的类,具体看下方解析
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
Iterator var4 = autoConfigurationEntry.getConfigurations().iterator();
while(var4.hasNext()) {
String importClassName = (String)var4.next();
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
// 返回 自动装配类 Entry 集合
public Iterable<Entry> selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
} else {
Set<String> allExclusions = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
Set<String> processedConfigurations = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
processedConfigurations.removeAll(allExclusions);
return (Iterable)this.sortAutoConfigurations(processedConfigurations, this.getAutoConfigurationMetadata()).stream().map((importClassName) -> {
return new Entry((AnnotationMetadata)this.entries.get(importClassName), importClassName);
}).collect(Collectors.toList());
}
}
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
return (new AutoConfigurationSorter(this.getMetadataReaderFactory(), autoConfigurationMetadata)).getInPriorityOrder(configurations);
}
private MetadataReaderFactory getMetadataReaderFactory() {
try {
return (MetadataReaderFactory)this.beanFactory.getBean("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", MetadataReaderFactory.class);
} catch (NoSuchBeanDefinitionException var2) {
return new CachingMetadataReaderFactory(this.resourceLoader);
}
}
}
AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry
方法 :
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 读取自动装配类名
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 根据 @Conditional 注解过滤不需要自动装配的类
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
getCandidateConfigurations 方法:读取 META-INF/spring.factories 中 key 为 org.springframework.boot.autoconfigure.EnableAutoConfiguration 的类名列表
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
执行 configurations = this.getConfigurationClassFilter().filter(configurations); 前需要自动装配的类名称configurations集合(133个):
执行 configurations = this.getConfigurationClassFilter().filter(configurations); 后需要自动装配的类名称configurations集合(24个):
parse 方法执行完后 org.springframework.context.annotation.ConfigurationClassParser 对象 Map<ConfigurationClass, ConfigurationClass> configurationClasses 属性值如下: