前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springboot启动过程解析

springboot启动过程解析

原创
作者头像
一点一线
发布2022-04-05 20:35:32
4570
发布2022-04-05 20:35:32
举报
文章被收录于专栏:计算机技术计算机技术

虽然golang开始在后台开发横行,但是springboot还是目前大多数企业使用的技术栈。由于其成熟性,丰富的组件以及生态环境,是很多公司的首选。学习springboot需要了解其启动过程,对原理的理解可以避免停留在CRUD层面,对底层有很多深入的理解可以助力我们成长,解决深层次问题。

  1. 先看一下个简单的demo, 通过ideal创建的工程就会自动生成。
代码语言:javascript
复制
@SpringBootApplication
public class DemoApplication {

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

}

2.SpringApplication构造函数

代码语言:javascript
复制
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
  // 资源加载器
   this.resourceLoader = resourceLoader;
   Assert.notNull(primarySources, "PrimarySources must not be null");
  // 配置资源,类从哪里来
   this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
  // 是否为web类型
   this.webApplicationType = WebApplicationType.deduceFromClasspath();
  // 创建ApplicationContextInitializer并初始化
   this.bootstrapRegistryInitializers = new ArrayList<>(
         getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
   setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
  // ApplicationListener 初始化
   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  // 运行的主类
   this.mainApplicationClass = deduceMainApplicationClass();
}

3.run函数

代码语言:javascript
复制
public ConfigurableApplicationContext run(String... args) {
   long startTime = System.nanoTime();
  // 类加载上线文
   DefaultBootstrapContext bootstrapContext = createBootstrapContext();
   ConfigurableApplicationContext context = null;
   configureHeadlessProperty();
  // 获取构造函数中创建的listener
   SpringApplicationRunListeners listeners = getRunListeners(args);
  // 开始监听
   listeners.starting(bootstrapContext, this.mainApplicationClass);
   try {
     //参数承载类
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
     //配置环境
     ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
      configureIgnoreBeanInfo(environment);
     // 打印banner
      Banner printedBanner = printBanner(environment);
     //创建主的Bean
      context = createApplicationContext();
      context.setApplicationStartup(this.applicationStartup);
     //初始化工作
      prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
     //刷新
     refreshContext(context);
      afterRefresh(context, applicationArguments);
      Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
      }
      // 初始化监听完成
      listeners.started(context, timeTakenToStartup);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, listeners);
      throw new IllegalStateException(ex);
   }
   try {
      Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
      //进入准备阶段
      listeners.ready(context, timeTakenToReady);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

4.prepareContext 资源加载,并且初始化。

代码语言:javascript
复制
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
      ApplicationArguments applicationArguments, Banner printedBanner) {
   context.setEnvironment(environment);
  // 初始化资源加载设置
   postProcessApplicationContext(context);
  // 开始初始化
   applyInitializers(context);
   listeners.contextPrepared(context);
   bootstrapContext.close(context);
   if (this.logStartupInfo) {
      logStartupInfo(context.getParent() == null);
      logStartupProfileInfo(context);
   }
   // Add boot specific singleton beans
   ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
   beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
   if (printedBanner != null) {
      beanFactory.registerSingleton("springBootBanner", printedBanner);
   }
  // 依赖注入
   if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {
      ((AbstractAutowireCapableBeanFactory) beanFactory).setAllowCircularReferences(this.allowCircularReferences);
      if (beanFactory instanceof DefaultListableBeanFactory) {
         ((DefaultListableBeanFactory) beanFactory)
               .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
      }
   }
  // 懒加载,解决循环依赖问题
   if (this.lazyInitialization) {
      context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
   }
   // Load the sources
   Set<Object> sources = getAllSources();
   Assert.notEmpty(sources, "Sources must not be empty");
  //加载初始化bean,IOC的实现
   load(context, sources.toArray(new Object[0]));
   listeners.contextLoaded(context);
}

5.refresh ioc的最后一步,对bean进行后续处理。

代码语言:javascript
复制
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      //准备context用于刷新
      prepareRefresh();
     
      //通知子类刷新bean
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 准备beanfactory
      prepareBeanFactory(beanFactory);

      try {
         // 允许beanfactory刷新子类
         postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // 把bean注册到context中
         invokeBeanFactoryPostProcessors(beanFactory);

         // 注册processor用于bean的创建
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // 初始化资源信息
         initMessageSource();

         //广播信息初始化
         initApplicationEventMulticaster();

         //对特殊的子类进行刷新
         onRefresh();

         //检查注册的bean并且监听
         registerListeners();

         //初始化其他类懒加载的实力
         finishBeanFactoryInitialization(beanFactory);

         // 发布刷新完毕的消息
         finishRefresh();
      }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
网站建设
网站建设(Website Design Service,WDS),是帮助您快速搭建企业网站的服务。通过自助模板建站工具及专业设计服务,无需了解代码技术,即可自由拖拽模块,可视化完成网站管理。全功能管理后台操作方便,一次更新,数据多端同步,省时省心。使用网站建设服务,您无需维持技术和设计师团队,即可快速实现网站上线,达到企业数字化转型的目的。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档