springboot启动源码详解

学习spring这个框架,我们总是有种感觉,会用但是不懂,“会用”是因为spring的框架利用约定大于配置的原则帮我们封装好了所有的启动配置类,这样我们使用起来的入门门槛就比较低了,只要照着官方的文档配置,一般都不会有问题,“不懂”是因为我们不知道他的底层到底是怎么实现的,有种雾里看花的感觉,一旦我们想拓展下spring的框架,就无从下手了, spring作为一个优秀的开源框架,我们很有必要去探究下他的底层实现,同时作为一名程序员,知其然也要知其所以然,要有求知欲望,这样才能站得高看的远,废话不多说,今天我们就来详细剖析下spring的启动过程(文中可能有错误的地方,希望各位看官能及时指出,非常感谢):

先看一个spring启动的例子:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
     ConfigurableApplicationContext context =  SpringApplication.run(Application.class,args);
    }
}

只要这一行启动代码,spring就为我们默认配置好了一切项目运行所必须的环境,是不是很简单,就从这里入手,看看spring到底做了什么!

public static ConfigurableApplicationContext run(Object source, String... args) {
    return run(new Object[]{source}, args);
}

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    //调用springApplication的构造函数
    return (new SpringApplication(sources)).run(args);
}
public SpringApplication(Object... sources) {
   //创建一个新的SpringApplication对象
   initialize(sources);
}
private void initialize(Object[] sources) {
   if (sources != null && sources.length > 0) {
      this.sources.addAll(Arrays.asList(sources));
   }
   //判断是不是一个web的应用,判断的逻辑是加载 "javax.servlet.Servlet",
   //"org.springframework.web.context.ConfigurableWebApplicationContext"这两个类,如果加载成功,则是web应用
   // this.webEnvironment = true
   this.webEnvironment = deduceWebEnvironment();
   //初始化各种初始化器的实例,这些势力将会在创建好ApplicationContext后,prepare时进行调用,这里只是先对其进行实例化设值;
   //这里总共有6个Initializers,是从spring.factories配置文件里面读取到的
  //0 = {DelegatingApplicationContextInitializer@2208} 
  //1 = {ContextIdApplicationContextInitializer@2209} 
  //2 = {ConfigurationWarningsApplicationContextInitializer@2210} 
  //3 = {ServerPortInfoApplicationContextInitializer@2211} 
  //4 = {SharedMetadataReaderFactoryContextInitializer@2212} 
  //5 = {AutoConfigurationReportLoggingInitializer@2213} 


   setInitializers((Collection) getSpringFactoriesInstances(
         ApplicationContextInitializer.class));
   //设置10个listeners,实现原理同上,这里就不再赘述了,找到所有实现了ApplicationListener接口的实现类并实例化
   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
   //从堆栈中找到启动类的信息并加载启动类,这里就是加载Application类,到这里,初始化的工作基本完成,下面开始执行Application  //的run方法
   this.mainApplicationClass = deduceMainApplicationClass();
}
public ConfigurableApplicationContext run(String... args) {
    //new一个执行时间的监视器,记录spring启动的开始、结束时间;
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    //设置system的java.awt.headless的属性
    this.configureHeadlessProperty();
   //初始化一个SpringApplicationRunListeners对象,里面包含SpringApplicationRunListener数组,这里的数组只有一个监听器
   //对象EventPublishingRunListener,他会发布一个ApplicationStartedEvent事件,我们可以监听这个事件做一些初始化的工作,
//其初始化SpringApplicationRunListener的实现原理同上面的ApplicationListener
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting();

    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        //因为是一个web应用,所以这里初始化一
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值