spring boot启动流程


Springboot是基于Spring4的条件注册的一套快速开发整合包。它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具;

SpringBoot的项目启动类只有一个注解@SpringBootApplication和一个run方法。

@SpringBootApplication

public class Application {

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

}

直接点进@SpringBootApplication

@SpringBootApplication:

包含了@SpringBootConfiguration(打开是@Configuration),

@EnableAutoConfiguration,

@ComponentScan注解。

@Configuration

这里的启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类。任何一个标注@Configuration的Java类定义都是一个JavaConfig配置类。任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id。

@ComponentScan

@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。

@EnableAutoConfiguration

最关键的是@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。该配置模块的主要使用到了SpringFactoriesLoader。

SpringFactoriesLoader详解

SpringFactoriesLoader为Spring工厂加载器,该对象提供了loadFactoryNames方法,入参为factoryClass和classLoader即需要传入工厂类名称和对应的类加载器,方法会根据指定的classLoader,加载该类加器搜索路径下的指定文件,即spring.factories文件,传入的工厂类为接口,而文件中对应的类则是接口的实现类,或最终作为实现类。获取到这些实现类的类名后,loadFactoryNames方法返回类名集合,方法调用方得到这些集合后,再通过反射获取这些类的类对象、构造方法,最终生成实例。

AutoConfigurationImportSelector

该类主要关注selectImports方法

public String[] selectImports(AnnotationMetadata annotationMetadata) {
  if (!this.isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
  } else {
      AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
      AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
      return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
  }
}

该方法在springboot启动流程——bean实例化前被执行,返回要实例化的类信息列表。如果获取到类信息,spring可以通过类加载器将类加载到jvm中,现在我们已经通过spring-boot的starter依赖方式依赖了我们需要的组件,那么这些组件的类信息在select方法中就可以被获取到。

其中最重要的是getAutoConfigurationEntry里边调用了getCandidateConfigurations方法

 

 

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}

其返回一个自动配置类的类名列表,方法调用了loadFactoryNames方法,查看该方法

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
   String factoryTypeName = factoryType.getName();
   return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

自动配置器会跟根据传入的factoryClass.getName()到项目系统路径下所有的spring.factories文件中找到相应的key,从而加载里面的类。

 

借鉴来自: 作者:祖大帅 链接:https://juejin.im/post/5b679fbc5188251aad213110 来源:掘金

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM