栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 核心原理分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 核心原理分析

spring-boot-loader

  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 beanFactoryPostProcessors) {

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

    if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List regularPostProcessors = new linkedList();
      List registryProcessors = new linkedList();

      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 currentRegistryProcessors = new ArrayList();

      // 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 configCandidates = new ArrayList();
    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() {
      @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 candidates = new linkedHashSet(configCandidates);
    Set alreadyParsed = new HashSet(configCandidates.size());
    do {
      //解析我们配置SpringBoot启动类:BootApplication
      parser.parse(candidates);
      parser.validate();

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

    //...
  }
ConfigurationClassParser具体的解析操作:
public void parse(Set configCandidates) {
    this.deferredimportSelectors = new linkedList();

    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 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 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 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 configurations = this.getCandidateConfigurations(annotationmetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                configurations = this.sort(configurations, autoConfigurationmetadata);
                Set 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 loadFactoryNames(Class factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        //从各个自动配置的Starter的meta-INF/spring.factories配置文件中导入自动配置类
        Enumeration 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将自动配置类信息导入后会加载到容器中,我们就可以在运行时获取这些配置类来使用了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/349524.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号