网上很多文章对于自动状态都是说的很含糊,而且是千篇一律。很多都是这个注解@EnableAutoConfiguration就自动完成了。怎么可能呢?注解永远都是死的,是需要某个代码去解析处理的
我今天就跟了下代码看看怎么回事
@Configuration这个注解从Spring3就有了,可不是一个新东西。他的作用就是解放配置文件。
我们可以看到
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }
就是一个@Configuration。
再看看 EnableAutoConfiguration,里面包含了一个 @Import
@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration
我们要分析的代码入口在 ConfigurationClassPostProcessor 。确切的说是 ConfigurationClassParser.parse
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
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());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
processDeferredImportSelectors();//对AutoConfigurationImportSelector的解析在这里
}
继续往里面看 还是在 ConfigurationClassParser
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // Recursively process any member (nested) classes first processMemberClasses(configClass, sourceClass); // Process any @PropertySource annotations for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } // Process any @ComponentScan annotations Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { for (AnnotationAttributes componentScan : componentScans) { // The config class is annotated with @ComponentScan -> perform the scan immediately Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if needed 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()); } } } } // Process any @Import annotations processImports(configClass, sourceClass, getImports(sourceClass), true);
注意绿色的注解,processImports专门负责解析 @Import
我们直接跳到 processDeferredImportSelectors
private void processDeferredImportSelectors() { List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;//见截图 this.deferredImportSelectors = null; if (deferredImports == null) { return; } deferredImports.sort(DEFERRED_IMPORT_COMPARATOR); Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>(); Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>(); for (DeferredImportSelectorHolder deferredImport : deferredImports) { Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup(); DeferredImportSelectorGrouping grouping = groupings.computeIfAbsent( (group == null ? deferredImport : group), (key) -> new DeferredImportSelectorGrouping(createGroup(group))); grouping.add(deferredImport); configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getConfigurationClass()); } for (DeferredImportSelectorGrouping grouping : groupings.values()) { grouping.getImports().forEach((entry) -> { ConfigurationClass configurationClass = configurationClasses.get( entry.getMetadata()); try { processImports(configurationClass, asSourceClass(configurationClass), asSourceClasses(entry.getImportClassName()), false); }
在这里有两个对象一个是我们写main方法所在的bean就是用@SpringBootApplication注解的bean,另一个就是AutoConfigurationImportSelector
所以自动装配发生作用的地点是在 ConfigurationClassPostProcessor 这个BeanFactoryPostProcessor对于注解@Configuration的处理中完成的
本篇只分析到这里,对于AutoConfigurationImportSelector的详细调用过程,留到下一篇
原文:https://www.cnblogs.com/juniorMa/p/14132352.html