重庆住建部官网,济南百度整站seo推广,ui培训班 千锋教育,wordpress开始安装springboot源码(二)#xff1a;自动装配原理
在之前的课程中我们讲解了springboot的启动过程#xff0c;其实在面试过程中问的最多的可能是自动装配的原理#xff0c;而自动装配是在启动过程中完成#xff0c;只不过在刚开始的时候我们选择性的跳过了#xff0c;下面详…springboot源码(二)自动装配原理
在之前的课程中我们讲解了springboot的启动过程其实在面试过程中问的最多的可能是自动装配的原理而自动装配是在启动过程中完成只不过在刚开始的时候我们选择性的跳过了下面详细讲解自动装配的过程。
1、在springboot的启动过程中有一个步骤是创建上下文如果不记得可以看下面的代码
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch new StopWatch();stopWatch.start();ConfigurableApplicationContext context null;CollectionSpringBootExceptionReporter exceptionReporters new ArrayList();configureHeadlessProperty();SpringApplicationRunListeners listeners getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments new DefaultApplicationArguments(args);ConfigurableEnvironment environment prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner printBanner(environment);context createApplicationContext();exceptionReporters getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);//此处完成自动装配的过程prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;}2、在prepareContext方法中查找load方法一层一层向内点击找到最终的load方法
//prepareContext方法private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);postProcessApplicationContext(context);applyInitializers(context);listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() null);logStartupProfileInfo(context);}// Add boot specific singleton beansConfigurableListableBeanFactory beanFactory context.getBeanFactory();beanFactory.registerSingleton(springApplicationArguments, applicationArguments);if (printedBanner ! null) {beanFactory.registerSingleton(springBootBanner, printedBanner);}if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// Load the sourcesSetObject sources getAllSources();Assert.notEmpty(sources, Sources must not be empty);//load方法完成该功能load(context, sources.toArray(new Object[0]));listeners.contextLoaded(context);}/*** Load beans into the application context.* param context the context to load beans into* param sources the sources to load* 加载bean对象到context中*/protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {logger.debug(Loading source StringUtils.arrayToCommaDelimitedString(sources));}//获取bean对象定义的加载器BeanDefinitionLoader loader createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);if (this.beanNameGenerator ! null) {loader.setBeanNameGenerator(this.beanNameGenerator);}if (this.resourceLoader ! null) {loader.setResourceLoader(this.resourceLoader);}if (this.environment ! null) {loader.setEnvironment(this.environment);}loader.load();}/*** Load the sources into the reader.* return the number of loaded beans*/int load() {int count 0;for (Object source : this.sources) {count load(source);}return count;}3、实际执行load的是BeanDefinitionLoader中的load方法如下 //实际记载bean的方法private int load(Object source) {Assert.notNull(source, Source must not be null);//如果是class类型启用注解类型if (source instanceof Class?) {return load((Class?) source);}//如果是resource类型启动xml解析if (source instanceof Resource) {return load((Resource) source);}//如果是package类型启用扫描包例如ComponentScanif (source instanceof Package) {return load((Package) source);}//如果是字符串类型直接加载if (source instanceof CharSequence) {return load((CharSequence) source);}throw new IllegalArgumentException(Invalid source type source.getClass());}4、下面方法将用来判断是否资源的类型是使用groovy加载还是使用注解的方式 private int load(Class? source) {//判断使用groovy脚本if (isGroovyPresent() GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {// Any GroovyLoaders added in beans{} DSL can contribute beans hereGroovyBeanDefinitionSource loader BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);load(loader);}//使用注解加载if (isComponent(source)) {this.annotatedReader.register(source);return 1;}return 0;}5、下面方法判断启动类中是否包含Component注解但是会神奇的发现我们的启动类中并没有该注解继续更进发现MergedAnnotations类传入了一个参数SearchStrategy.TYPE_HIERARCHY会查找继承关系中是否包含这个注解SpringBootApplication–SpringBootConfiguration–Configuration–Component,当找到Component注解之后会把该对象注册到AnnotatedBeanDefinitionReader对象中
private boolean isComponent(Class? type) {// This has to be a bit of a guess. The only way to be sure that this type is// eligible is to make a bean definition out of it and try to instantiate it.if (MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY).isPresent(Component.class)) {return true;}// Nested anonymous classes are not eligible for registration, nor are groovy// closuresreturn !type.getName().matches(.*\\$_.*closure.*) !type.isAnonymousClass() type.getConstructors() ! null type.getConstructors().length ! 0;
}/*** Register a bean from the given bean class, deriving its metadata from* class-declared annotations.* 从给定的bean class中注册一个bean对象从注解中找到相关的元数据*/private T void doRegisterBean(ClassT beanClass, Nullable String name,Nullable Class? extends Annotation[] qualifiers, Nullable SupplierT supplier,Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);ScopeMetadata scopeMetadata this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName (name ! null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers ! null) {for (Class? extends Annotation qualifier : qualifiers) {if (Primary.class qualifier) {abd.setPrimary(true);}else if (Lazy.class qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers ! null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}BeanDefinitionHolder definitionHolder new BeanDefinitionHolder(abd, beanName);definitionHolder AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}/*** Register the given bean definition with the given bean factory.* 注册主类如果有别名可以设置别名*/public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// Register bean definition under primary name.String beanName definitionHolder.getBeanName();registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.String[] aliases definitionHolder.getAliases();if (aliases ! null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}//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 {}//SpringBootConfiguration
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Configuration
public interface SpringBootConfiguration {}//Configuration
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Component
public interface Configuration {}当看完上述代码之后只是完成了启动对象的注入自动装配还没有开始下面开始进入到自动装配。
6、自动装配入口从刷新容器开始
Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 此处是自动装配的入口invokeBeanFactoryPostProcessors(beanFactory);}7、在invokeBeanFactoryPostProcessors方法中完成bean的实例化和执行
/*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* pMust be called before singleton instantiation.*/protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {//开始执行beanFactoryPostProcessor对应实现类,需要知道的是beanFactoryPostProcessor是spring的扩展接口在刷新容器之前该接口可以用来修改bean元数据信息PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() null beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}8、查看invokeBeanFactoryPostProcessors的具体执行方法 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListBeanFactoryPostProcessor beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.SetString processedBeans new HashSet();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry (BeanDefinitionRegistry) beanFactory;ListBeanFactoryPostProcessor regularPostProcessors new ArrayList();ListBeanDefinitionRegistryPostProcessor registryProcessors new ArrayList();//开始遍历三个内部类如果属于BeanDefinitionRegistryPostProcessor子类加入到bean注册的集合否则加入到regularPostProcessorsfor (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor (BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.ListBeanDefinitionRegistryPostProcessor currentRegistryProcessors new ArrayList();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.//通过BeanDefinitionRegistryPostProcessor获取到对应的处理类“org.springframework.context.annotation.internalConfigurationAnnotationProcessor”但是需要注意的是这个类在springboot中搜索不到这个类的完全限定名在AnnotationConfigEmbeddedWebApplicationContext中在进行初始化的时候会装配几个类在创建AnnotatedBeanDefinitionReader对象的时候会将该类注册到bean对象中此处可以看到internalConfigurationAnnotationProcessor为bean名称容器中真正的类是ConfigurationClassPostProcessorString[] postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//首先执行类型为PriorityOrdered的BeanDefinitionRegistryPostProcessor//PriorityOrdered类型表明为优先执行for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//获取对应的beancurrentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//用来存储已经执行过的BeanDefinitionRegistryPostProcessorprocessedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);//开始执行装配逻辑invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.//其次执行类型为Ordered的BeanDefinitionRegistryPostProcessor//Ordered表明按顺序执行postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.//循环中执行类型不为PriorityOrderedOrdered类型的BeanDefinitionRegistryPostProcessorboolean reiterate true;while (reiterate) {reiterate false;postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far. //执行父类方法优先执行注册处理类invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//执行有规则处理类invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.ListBeanFactoryPostProcessor priorityOrderedPostProcessors new ArrayList();ListString orderedPostProcessorNames new ArrayList();ListString nonOrderedPostProcessorNames new ArrayList();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.ListBeanFactoryPostProcessor orderedPostProcessors new ArrayList(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.ListBeanFactoryPostProcessor nonOrderedPostProcessors new ArrayList(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}9、开始执行自动配置逻辑启动类指定的配置非默认配置可以通过debug的方式一层层向里进行查找会发现最终会在ConfigurationClassParser类中此类是所有配置类的解析类所有的解析逻辑在parser.parse(candidates)中
public void parse(SetBeanDefinitionHolder configCandidates) {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);}}//执行配置类this.deferredImportSelectorHandler.process();}
-------------------protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {processConfigurationClass(new ConfigurationClass(metadata, beanName));}
-------------------protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}ConfigurationClass existingClass this.configurationClasses.get(configClass);if (existingClass ! null) {if (configClass.isImported()) {if (existingClass.isImported()) {existingClass.mergeImportedBy(configClass);}// Otherwise ignore new imported config class; existing non-imported class overrides it.return;}else {// Explicit bean definition found, probably replacing an import.// Lets remove the old one and go with the new one.this.configurationClasses.remove(configClass);this.knownSuperclasses.values().removeIf(configClass::equals);}}// Recursively process the configuration class and its superclass hierarchy.SourceClass sourceClass asSourceClass(configClass);do {//循环处理bean,如果有父类则处理父类直至结束sourceClass doProcessConfigurationClass(configClass, sourceClass);}while (sourceClass ! null);this.configurationClasses.put(configClass, configClass);}10、继续跟进doProcessConfigurationClass方法此方式是支持注解配置的核心逻辑
/*** Apply processing and build a complete {link ConfigurationClass} by reading the* annotations, members and methods from the source class. This method can be called* multiple times as relevant sources are discovered.* param configClass the configuration class being build* param sourceClass a source class* return the superclass, or {code null} if none found or previously processed*/Nullableprotected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)throws IOException {//处理内部类逻辑由于传来的参数是启动类并不包含内部类所以跳过if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// Recursively process any member (nested) classes firstprocessMemberClasses(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.info(Ignoring PropertySource annotation on [ sourceClass.getMetadata().getClassName() ]. Reason: Environment must implement ConfigurableEnvironment);}}// Process any ComponentScan annotations// 这里是根据启动类ComponentScan注解来扫描项目中的beanSetAnnotationAttributes 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//遍历项目中的bean如果是注解定义的bean则进一步解析SetBeanDefinitionHolder scannedBeanDefinitions this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand null) {bdCand holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {//递归解析所有的bean,如果有注解会进一步解析注解中包含的beanparse(bdCand.getBeanClassName(), holder.getBeanName());}}}}// Process any Import annotations//递归解析获取导入的配置类很多情况下导入的配置类中会同样包含导入类注解processImports(configClass, sourceClass, getImports(sourceClass), true);// Process any ImportResource annotations//解析ImportResource配置类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);}}// Process individual Bean methods//处理Bean注解修饰的类SetMethodMetadata beanMethods retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// Process default methods on interfaces// 处理接口中的默认方法processInterfaces(configClass, sourceClass);// Process superclass, if any//如果该类有父类则继续返回上层方法判断不为空则继续递归执行if (sourceClass.getMetadata().hasSuperClass()) {String superclass sourceClass.getMetadata().getSuperClassName();if (superclass ! null !superclass.startsWith(java) !this.knownSuperclasses.containsKey(superclass)) {this.knownSuperclasses.put(superclass, configClass);// Superclass found, return its annotation metadata and recursereturn sourceClass.getSuperClass();}}// No superclass - processing is completereturn null;}
11、查看获取配置类的逻辑
processImports(configClass, sourceClass, getImports(sourceClass), true);/*** Returns {code Import} class, considering all meta-annotations.*/private SetSourceClass getImports(SourceClass sourceClass) throws IOException {SetSourceClass imports new LinkedHashSet();SetSourceClass visited new LinkedHashSet();collectImports(sourceClass, imports, visited);return imports;}
------------------/*** Recursively collect all declared {code Import} values. Unlike most* meta-annotations it is valid to have several {code Import}s declared with* different values; the usual process of returning values from the first* meta-annotation on a class is not sufficient.* pFor example, it is common for a {code Configuration} class to declare direct* {code Import}s in addition to meta-imports originating from an {code Enable}* annotation.* 看到所有的bean都以导入的方式被加载进去*/private void collectImports(SourceClass sourceClass, SetSourceClass imports, SetSourceClass visited)throws IOException {if (visited.add(sourceClass)) {for (SourceClass annotation : sourceClass.getAnnotations()) {String annName annotation.getMetadata().getClassName();if (!annName.equals(Import.class.getName())) {collectImports(annotation, imports, visited);}}imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), value));}}12、继续回到ConfigurationClassParser中的parse方法中的最后一行,继续跟进该方法
this.deferredImportSelectorHandler.process()
-------------
public void process() {ListDeferredImportSelectorHolder deferredImports this.deferredImportSelectors;this.deferredImportSelectors null;try {if (deferredImports ! null) {DeferredImportSelectorGroupingHandler handler new DeferredImportSelectorGroupingHandler();deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);deferredImports.forEach(handler::register);handler.processGroupImports();}}finally {this.deferredImportSelectors new ArrayList();}}
---------------public void processGroupImports() {for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {grouping.getImports().forEach(entry - {ConfigurationClass configurationClass this.configurationClasses.get(entry.getMetadata());try {processImports(configurationClass, asSourceClass(configurationClass),asSourceClasses(entry.getImportClassName()), false);}catch (BeanDefinitionStoreException ex) {throw ex;}catch (Throwable ex) {throw new BeanDefinitionStoreException(Failed to process import candidates for configuration class [ configurationClass.getMetadata().getClassName() ], ex);}});}}
------------/*** Return the imports defined by the group.* return each import with its associated configuration class*/public IterableGroup.Entry getImports() {for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {this.group.process(deferredImport.getConfigurationClass().getMetadata(),deferredImport.getImportSelector());}return this.group.selectImports();}}
------------public DeferredImportSelector getImportSelector() {return this.importSelector;}
------------Overridepublic void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,() - String.format(Only %s implementations are supported, got %s,AutoConfigurationImportSelector.class.getSimpleName(),deferredImportSelector.getClass().getName()));AutoConfigurationEntry autoConfigurationEntry ((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);this.autoConfigurationEntries.add(autoConfigurationEntry);for (String importClassName : autoConfigurationEntry.getConfigurations()) {this.entries.putIfAbsent(importClassName, annotationMetadata);}}