SpringBoot自动装配原理(到注册beanDefinition)

SpringBoot自动装配原理(到注册beanDefinition)

总体结构:return (new SpringApplication(primarySources)).run(args);

new SpringApplication(primarySources

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.sources = new LinkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.addConversionService = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = new HashSet();
    this.isCustomEnvironment = false;
    this.lazyInitialization = false;
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

.run(args)

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
    this.configureHeadlessProperty();
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting();

    Collection exceptionReporters;
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
        this.configureIgnoreBeanInfo(environment);
        Banner printedBanner = this.printBanner(environment);
        context = this.createApplicationContext();
        exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
      //这里主要是找到 TianmaoApplication 并注册进 BeanDefinitionMap 中
        this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      //**关键步骤,这里完成了扫描,注册、实例化、初始化等几乎所有的工作  
      this.refreshContext(context);
      
        this.afterRefresh(context, applicationArguments);
        stopWatch.stop();
        if (this.logStartupInfo) {
            (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
        }

        listeners.started(context);
        this.callRunners(context, applicationArguments);
    } catch (Throwable var10) {
        this.handleRunFailure(context, var10, exceptionReporters, listeners);
        throw new IllegalStateException(var10);
    }

    try {
        listeners.running(context);
        return context;
    } catch (Throwable var9) {
        this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
        throw new IllegalStateException(var9);
    }
}

1、创建Spring应用程序 new SpringApplication(primarySources)

//对SpringApplication进行初始化
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//getSpringFactoriesInstances方法内部通过反射实例化所有的初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//getSpringFactoriesInstances方法内部通过反射实例化所有的监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//获取主要应用类:TianmaoApplication(自己的项目入口类)
this.mainApplicationClass = this.deduceMainApplicationClass();

2、一些准备工作

//2.1开启计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
//2.2配置系统属性,意义不大
this.configureHeadlessProperty();
//2.3注册监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();

Collection exceptionReporters;
try {
  //2.4加载命令行参数
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
  //2.5准备当前应用程序的环境
    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
  //2.6设置系统属性,保证某些bean不会添加到准备的环境中
    this.configureIgnoreBeanInfo(environment);
  //2.7准备springboot的旗帜
    Banner printedBanner = this.printBanner(environment);
  //2.8准备应用上下文对象,根据当前应用程序的类型来判断创建什么格式的上下文对象
    context = this.createApplicationContext();
  //2.9设置异常报告对象
    exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
  //2.10 准备当前上下文对象(AnnotationConfigServletWebServerApplicationContext)
    this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

3、准备当前上下文中有一个load方法,最终目的是将入口类注册进beanDefinitionMap中,方便后面实例化

//3.1 创建了一个BeanDefinitionLoader
BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);
//3.2 遍历前面的主要数据源,即 class com.lzy.tianmao.TianmaoApplication,然后通过            this.annotatedReader.register(new Class[]{source});把这个类注册进beanDefinitionMap中
loader.load();

4、(关键操作)刷新容器 this.refreshContext(context);

public void refresh() throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
      //对beanFactory进行了初始化
        this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
          //4.1 执行beanFactory的后置处理器,添加一系列的beanDefinition
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
          //根据beanDefinition实例化并初始化 单例且非懒加载的 bean
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();

4.1 调用配置类后置处理器 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法

/*
   BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor的子类
* 执行时间:
*
* 1、通过 ioc.add()添加的 程序员自己的实现了 BeanDefinitionRegistryPostProcessor
* 2、内置的  BeanDefinitionRegistryPostProcessor接口的实现类
* 3、通过@Component等注解添加的 程序员自己的实现了 BeanDefinitionRegistryPostProcessor
*     先执行实现了 ordered的,再执行没有实现ordered的
*
* 4、执行 直接实现BeanDefinitionRegistryPostProcessor的实现类对应重写BeanFactoryPostProcessor的方法(
      因为实现bdrpp的同时也间接实现了bfpp,所以有两个需要重写的方法,现在执行bfpp的重写方法)
* 5、程序员通过api注册的后置处理器,它直接实现了 BeanFactoryPostProcessor,而没有实现 bdrpp
  6、执行内置的和程序员通过注解注册的直接实现bfpp接口的实现类
      实现了priorityOrdered
      实现了ordered
      没有实现order的
*/

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//ConfigurationClassPostProcessor的调用方法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    } else if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
    } else {
        this.registriesPostProcessed.add(registryId);
      //处理配置类的定义信息
        this.processConfigBeanDefinitions(registry);
    }
}

4.2 首先从候选的beanDefinition中筛选出配置类的 beanDefinition

4.3 对筛选出的配置类的beanDefinition进行解析 parser.parse(candidates);

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
   String[] candidateNames = registry.getBeanDefinitionNames();

   for (String beanName : candidateNames) {
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      //判读当前的 BeanDefinition所描述的 bean所对应的类 是不是一个配置类
      //如果他是一个配置类 那么他究竟是什么样的配置
      // 1 FullConfiguration 全配置类
      // 2 LiteConfiguration 半配置类
      // 3 不是一个配置类
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
            ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
         //processed 是否有当前BeanDefinition进行了配置的解析判断
         //是否已经确定了当前BeanDefinition 的类型
         if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
         }
      }
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
         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;
   if (registry instanceof SingletonBeanRegistry) {
      sbr = (SingletonBeanRegistry) registry;
      if (!this.localBeanNameGeneratorSet) {
         BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
         if (generator != null) {
            this.componentScanBeanNameGenerator = generator;
            this.importBeanNameGenerator = generator;
         }
      }
   }

   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());
   do {
     //解析配置类,包括注解,接口实现方法,重写父类的方法。这里主要是获取 @EnableAutoConfiguration注解中所有的需要自动配置的类信息。
      parser.parse(candidates);
      parser.validate();
	
     //这里就拿到了所有配置类 并存在configClasses中。
      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());
      }
     // 对拿到的所有需要自动配置类注册BeanDefinition。(为实例化做准备)
      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();
   }
}

4.4 根据配置类的类型进行解析

    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        Iterator var2 = configCandidates.iterator();

        while(var2.hasNext()) {
            BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
            BeanDefinition bd = holder.getBeanDefinition();

            try {
              //通过@Configuration注解进行配置的
                if (bd instanceof AnnotatedBeanDefinition) {

/*
这里通过解析tianmaoApplication上的注解信息找到了自动配置的相关类(用到了递归遍历):
    @EnableAutoConfiguration中的@Import(AutoConfigurationImportSelector.class)
*/
                    //AnnotatedBeanDefinition)bd).getMetadata()是 @SpringBootApplication
 				  //holder.getBeanName()是 "tianmaoApplication"
                    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);
            }
        }
// 这里将处理上面解析到的 @Import(AutoConfigurationImportSelector.class)
        this.deferredImportSelectorHandler.process();
    }

解析过程:寻找AutoConfigurationImportSelector

4.5 实例化配置类ConfigurationClass并设置属性AnnotationMetadata为@SpringBootApplication,设置属性beanName为tianmaoApplication

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
    this.processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

4.6 根据配置类ConfigurationClass 初始化了配置类解析器ConfigurationClassParser,并开始真正的解析工作

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
    if (!this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
        ConfigurationClass existingClass = (ConfigurationClass)this.configurationClasses.get(configClass);
        if (existingClass != null) {
            if (configClass.isImported()) {
                if (existingClass.isImported()) {
                    existingClass.mergeImportedBy(configClass);
                }

                return;
            }

            this.configurationClasses.remove(configClass);
            this.knownSuperclasses.values().removeIf(configClass::equals);
        }

        ConfigurationClassParser.SourceClass sourceClass = this.asSourceClass(configClass, filter);

        do {
          // 真正开始处理配置类
            sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
        } while(sourceClass != null);

        this.configurationClasses.put(configClass, configClass);
    }
}

4.7 执行扫描工作,判断配置类(当前是tianmaoApplication)上有没有@Component、@PropertySources、@ComponentScan、@ComponentScans、@Bean、@Import、@ImportResource等

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);
    }
//解析@PropertySource注解,即如果有该注解,执行该注解相应的功能
    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");
        }
    }
  
//解析@ComponentScan,即如果有该注解,执行该注解相应的功能
    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注释(自动装配在这里)
    this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
//处理@ImportResource注解
  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);
        }
    }
//处理@Bean
    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;
}

4.8 解析@Import注解来实现自动装配

//参数:
//configClass ==>ConfigurationClass:beanName 'tianmaoApplication', com.lzy.tianmao.TianmaoApplication
//sourceClass ==>com.lzy.tianmao.TianmaoApplication
//filter ==>ConfigurationClassParser
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);

this.getImports(sourceClass) 递归查找 TianmaoApplication上的@Import注解

private Set<ConfigurationClassParser.SourceClass> getImports(ConfigurationClassParser.SourceClass sourceClass) throws IOException {
  //存储找到的@Import
    Set<ConfigurationClassParser.SourceClass> imports = new LinkedHashSet();
    Set<ConfigurationClassParser.SourceClass> visited = new LinkedHashSet();
  //开始查找
    this.collectImports(sourceClass, imports, visited);
    return imports;
}
private void collectImports(ConfigurationClassParser.SourceClass sourceClass, Set<ConfigurationClassParser.SourceClass> imports, Set<ConfigurationClassParser.SourceClass> visited) throws IOException {
    if (visited.add(sourceClass)) {
        Iterator var4 = sourceClass.getAnnotations().iterator();

        while(var4.hasNext()) {
            ConfigurationClassParser.SourceClass annotation = (ConfigurationClassParser.SourceClass)var4.next();
            String annName = annotation.getMetadata().getClassName();
            if (!annName.equals(Import.class.getName())) {
              //递归查找
                this.collectImports(annotation, imports, visited);
            }
        }
/*
此时imports中存储了:
      @EnableAutoConfiguration中的 @Import(AutoConfigurationImportSelector.class)
      @AutoConfigurationPackage中的 @Import(AutoConfigurationPackages.Registrar.class)
*/
        imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
    }

}

执行过程:处理AutoConfigurationImportSelector:得到spring.factories中的自动配置类

4.9处理找到的 AutoConfigurationImportSelector

//处理程序入口
this.deferredImportSelectorHandler.process();
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);
          
          //处理器(ConfigurationClassParser)处理imports集合中的类
            handler.processGroupImports();
        }
    } finally {
        this.deferredImportSelectors = new ArrayList();
    }

}
public void processGroupImports() {
    Iterator var1 = this.groupings.values().iterator();

while(var1.hasNext()) {
        ConfigurationClassParser.DeferredImportSelectorGrouping grouping = (ConfigurationClassParser.DeferredImportSelectorGrouping)var1.next();
        Predicate<String> exclusionFilter = grouping.getCandidateFilter();
      
      // getImports()
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);
            }
        });
      
}
}
public Iterable<Entry> getImports() {
    Iterator var1 = this.deferredImports.iterator();

    while(var1.hasNext()) {
        ConfigurationClassParser.DeferredImportSelectorHolder deferredImport = (ConfigurationClassParser.DeferredImportSelectorHolder)var1.next();
      //process
        this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector());
    }

    return this.group.selectImports();
}
public 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(annotationMetadata);
   this.autoConfigurationEntries.add(autoConfigurationEntry);
   for (String importClassName : autoConfigurationEntry.getConfigurations()) {
      this.entries.putIfAbsent(importClassName, annotationMetadata);
   }
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
   }
   AnnotationAttributes attributes = getAttributes(annotationMetadata);
  
  
  //getCandidateConfigurations获取spring.factories中所有自动配置类的全类名(124个)
   List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
  
  //后序的一些处理:排除重复的和不需要的
   configurations = removeDuplicates(configurations);
   Set<String> exclusions = getExclusions(annotationMetadata, attributes);
   checkExcludedClasses(configurations, exclusions);
   configurations.removeAll(exclusions);
   configurations = getConfigurationClassFilter().filter(configurations);
   fireAutoConfigurationImportEvents(configurations, exclusions);
   return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  /*
    getSpringFactoriesLoaderFactoryClass指定spring.factories中的 EnableAutoConfiguration所对应的类
  	SpringFactoriesLoader.loadFactoryNames加载spring.factories中所指定的类
  */
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
         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;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
//得到 EnableAutoConfiguration.class;
  return EnableAutoConfiguration.class;
}

spring.factories中的 EnableAutoConfiguration对应的所有配置类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

此时得到一个集合:configurationClasses,里面包含了自动装配的类

回到配置类后置处理器 ConfigurationClassPostProcessor 的 processConfigBeanDefinitions 方法,继续执行解析后的操作:

do {
  //解析
    parser.parse(candidates);
    parser.validate();
  //拿到刚才解析到的 configurationClasses
    Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
    configClasses.removeAll(alreadyParsed);
  //创建ConfigurationClassBeanDefinitionReader来根据class创建对应的beanDefinition
    if (this.reader == null) {
        this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
    }
//注册所有自动配置类的beanDefinition到beanFactory中的BeanDefinitionMap
    this.reader.loadBeanDefinitions(configClasses);
    alreadyParsed.addAll(configClasses);
    candidates.clear();

5、计时结束 stopWatch.stop();

6、监听器运行 listeners.started(context);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值