SpringBoot源码解析之SpringApplication构造函数初始化过程

过程解析

我们的程序执行到SpringApplication.run()时,第一步就是先调用SpringApplication的构造函数,入参就是带了@SpringBootApplication注解的启动类。
我们主要是看initialize里面做了什么。
SpringApplication(Object... sources)
// sources就是带了@SpringBootApplication注解的启动类
——》initialize(sources);
    // this.sources是一个LinkedHashSet,将我们入参的第一个class参数加到数组里面
    ——》this.sources.addAll(Arrays.asList(sources));
    /** 推断是否是web环境,[javax.servlet.Servlet, org.springframework.web.context.ConfigurableWebApplicationContext]这两个类都在应用环境中存在就是web环境
    通过ClassUtils.isPresent(className, null)判断应用环境中是否存在一个className
    判断逻辑:
    1、先到primitiveTypeNameMap(只缓存double等基本数据类型)这个HashMap查看有没有
    2、再到commonClassCache(缓存java.lang.Throwable等常用的bean)这个HashMap查看有没有
    3、使用AppClassLoader类加载器初始化类,若初始化不成功,使用Class.forName(name)初始化,完整的逻辑是:return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
    */
    ——》this.webEnvironment = deduceWebEnvironment();
    /**
    从META-INF/spring.factories中读取应用上下文初始化器ApplicationContextInitializer实现类的类列表,并将初始化后的应用上下文初始化器,加到List<ApplicationContextInitializer<?>> initializers中提供给后面的步骤使用
    读取到的配置有6个:分别从spring-boot-xxx.jar、spring-boot-autoconfigure-xxx.jar中读取
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
    */
    ——》setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    /**
    从META-INF/spring.factories中读取应用监听器ApplicationListener实现类的类列表,并将初始化后的应用监听器加到List<ApplicationListener<?>> listeners;中提供给后面的步骤使用
    读取到的配置有13个:
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener,\
org.springframework.boot.autoconfigure.BackgroundPreinitializer,\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener\
    */
    ——》setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    /** 推断带有main函数的类是哪个,从我们程序的调用栈中查找,函数名等于main的就是,返回初始化后的类
    org.springframework.boot.SpringApplication.deduceMainApplicationClass
    org.springframework.boot.SpringApplication.initialize
    org.springframework.boot.SpringApplication.<init>
    org.springframework.boot.SpringApplication.run
    org.springframework.boot.SpringApplication.run
    com.dameng.booking.HairBookingApplication.main
    */
    ——》this.mainApplicationClass = deduceMainApplicationClass();
 

总结

构造SpringApplication(Object... sources)主要做了几件事情
1、判断是否web环境赋给变量this.webEnvironment
2、读取META-INF/spring.factories配置的应用初始化器,并将初始化后的应用上下文初始化器,加到List<ApplicationContextInitializer<?>> initializers中提供给后面的步骤使用
3、读取META-INF/spring.factories配置的应用监听器,并将初始化后的应用监听器加到List<ApplicationListener<?>> listeners;中提供给后面的步骤使用
4、推断启动类是哪个,并赋给变量this.mainApplicationClass

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值