SpringBoot 核心原理分析

spring-boot-loader

image-20210602165847089

  1. maven将SpringBoot启动类打到fatJar
  2. JarLauncher
  3. SpringApplication

SpringBoot项目的入口

启动类

@SpringBootApplication
public class BootApplication {
    
    

    public static void main(String[] args){
    
    
        SpringApplication.run(BootApplication.class,args);
    }
}

SpringApplication的run方法

//AbstractApplicationContext#refresh
public ConfigurableApplicationContext run(String... args) {
    
    
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
    
    
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
          args);
      // 准备配置环境,读取配置文件到environment,你写的一大堆配置都在这读取
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
          applicationArguments);
      Banner printedBanner = printBanner(environment);
      //创建应用上下文
      context = createApplicationContext();
      analyzers = new FailureAnalyzers(context);
      //准备上下文环境,注册bean定义到context,这里的自定义Bean目前只有:
      //BootApplication,我们自定义的启动类
      prepareContext(context, environment, listeners, applicationArguments,
          printedBanner);
      //刷新上下文,这块是关键逻辑
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
    
    
        new StartupInfoLogger(this.mainApplicationClass)
            .logStarted(getApplicationLog(), stopWatch);
      }
      return context;
    }
    catch (Throwable ex) {
    
    
      handleRunFailure(context, listeners, analyzers, ex);
      throw new IllegalStateException(ex);
    }
}

//AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
    
    
    synchronized (this.startupShutdownMonitor) {
    
    
        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 此处的beanFactory是DefaultListenableBeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        //为bean工厂添加ClassLoader和一些内置的BeanPostProcessor
        prepareBeanFactory(beanFactory);

        try {
    
    
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            //触发内部自动配置的BeanFactoryPostProcessor,SpringBoot自动配置就是在这扩展实现的
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }

        catch (BeansException ex) {
    
    
            //...
        }finally {
    
    
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    
    //主要逻辑在这里实现
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	//...
    }
  }


PostProcessorRegistrationDelegate

//ConfigurationClassPostProcessor类来解析@Configuration注解
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<String>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
    
    
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();

      for (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.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      //此处获取Spring内置的ConfigurationClassPostProcessor,用来处理@Configuration注解
      String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
    
    
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
          //此处实例化ConfigurationClassPostProcessor
          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
          processedBeans.add(ppName);
        }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      //处理@Configuration注解
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

       //以下代码省略...
    }
    //以下代码省略...
  }

@SpringBootApplication:

主要由:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解组成,本质是就是一个@Configuration类

@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{
    
    
    //以下代码省略...
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    
    

}
@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({
    
    EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    
    
    //以下代码省略...
}

ConfigurationClassPostProcessor解析配置@Configuration:

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

    for (String beanName : candidateNames) {
    
    
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
          ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
    
    
        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
    Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
    
    
      @Override
      public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
    
    
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
      }
    });

    // 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 && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
    
    
        BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
        this.componentScanBeanNameGenerator = generator;
        this.importBeanNameGenerator = generator;
      }
    }

    // Parse each @Configuration class
    ConfigurationClassParser parser = new ConfigurationClassParser(
        this.metadataReaderFactory, this.problemReporter, this.environment,
        this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
    do {
    
    
      //解析我们配置SpringBoot启动类:BootApplication
      parser.parse(candidates);
      parser.validate();

      //...
    }
    while (!candidates.isEmpty());

    //...
  }

ConfigurationClassParser具体的解析操作:

public void parse(Set<BeanDefinitionHolder> configCandidates) {
    
    
    this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();

    for (BeanDefinitionHolder holder : configCandidates) {
    
    
      BeanDefinition bd = holder.getBeanDefinition();
      try {
    
    
        if (bd instanceof AnnotatedBeanDefinition) {
    
    
          //1、执行具体的解析工作
          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) {
    
    
        //...
      }
    }
    //2、处理DeferredImportSelector,此处是:EnableAutoConfigurationImportSelector
    processDeferredImportSelectors();
}

//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
    //处理@ComponentScan注解,默认是BootApplication所在的包
    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
        //解析@ComponentScan扫描的包下面的组件,如:@Component,@Service等
        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)) {
    
    
            //此处递归解析组件中存在的@Configuration注解
            parse(bdCand.getBeanClassName(), holder.getBeanName());
          }
        }
      }
    }

    // Process any @Import annotations
    //处理@Import注解,此处是关键逻辑所在,主要完成两个事情:
    //1、递归解析@Import注解;2、处理@Import注解中配置的类,此处主要是将EnableAutoConfigurationImportSelector.class类找出来放在缓存中,让上面的 processDeferredImportSelectors();方法处理
    processImports(configClass, sourceClass, getImports(sourceClass), true);

    //...
}

//2、处理DeferredImportSelector,此处是:EnableAutoConfigurationImportSelector
private void processDeferredImportSelectors() {
    
    
    List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
    this.deferredImportSelectors = null;
    Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);

    for (DeferredImportSelectorHolder deferredImport : deferredImports) {
    
    
      ConfigurationClass configClass = deferredImport.getConfigurationClass();
      try {
    
    
        //获取自动配置的类信息,具体由EnableAutoConfigurationImportSelector导入
        String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
        processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
      }
      catch (BeanDefinitionStoreException ex) {
    
    
        throw ex;
      }
      catch (Throwable ex) {
    
    
        throw new BeanDefinitionStoreException(
            "Failed to process import candidates for configuration class [" +
            configClass.getMetadata().getClassName() + "]", ex);
      }
    }
  }

EnableAutoConfigurationImportSelector的selectImports方法:

public String[] selectImports(AnnotationMetadata annotationMetadata) {
    
    
        if (!this.isEnabled(annotationMetadata)) {
    
    
            return NO_IMPORTS;
        } else {
    
    
            try {
    
    
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                //具体由SpringFactoriesLoader实现自动配置类的导入工作
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                configurations = this.sort(configurations, autoConfigurationMetadata);
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.filter(configurations, autoConfigurationMetadata);
                this.fireAutoConfigurationImportListeners(configurations, exclusions);
                return (String[])configurations.toArray(new String[configurations.size()]);
            } catch (IOException var6) {
    
    
                throw new IllegalStateException(var6);
            }
        }
    }

SpringFactoriesLoader导入自动配置类:

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    
    
    String factoryClassName = factoryClass.getName();
    try {
    
    
        //从各个自动配置的Starter的META-INF/spring.factories配置文件中导入自动配置类
        Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
        ArrayList result = new ArrayList();

        while(urls.hasMoreElements()) {
    
    
            URL url = (URL)urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
        }

        return result;
    }
    catch (IOException ex) {
    
    
      //...
    }
  }

SpringBoot的核心技术原理

自动配置及Bean的自动发现,可以看到SpringBoot最终是使用SpringFactoriesLoader从各个Starter的META-INF/spring.factories配置文件中导入自动配置类信息的。SpringBoot将自动配置类信息导入后会加载到容器中,我们就可以在运行时获取这些配置类来使用了。

猜你喜欢

转载自blog.csdn.net/a1774381324/article/details/120931495
今日推荐