SpringBoot 2.x 嵌入式Servlet 启动原理

嵌入式Servlet 启动原理

1)SpringBoot 应用运行run() 方法

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		return run(new Class<?>[] { primarySource }, args);
	}                 |
	                 \|/
	                  |
 public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}

2) run()内

  • context = createApplicationContext();
    • 【创建IOC对象】
    • 如果是web应用 创建AnnotationConfigServletWebServerApplicationContext容器 或者 AnnotationConfigServletWebServerApplicationContext容器
  • 否则创建AnnotationConfigApplicationContext 容器
  • refreshContext(context);
  • 【 刷新IOC容器, 初始化容器,创建容器中的每一个组件】

3) refresh(context); 刷新刚刚创建创建的容器

   public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

4) onRefresh();

  • web Ioc 重写了该方法
   @Override
  protected void onRefresh() {
  	super.onRefresh();
  	try {
  		createWebServer();
  	}
  	catch (Throwable ex) {
  		throw new ApplicationContextException("Unable to start web server", ex);
  	}
  }

5)createWebServer();

  • 创建嵌入式Servlet容器
   private void createWebServer() {
   	WebServer webServer = this.webServer;
   	ServletContext servletContext = getServletContext();
   	if (webServer == null && servletContext == null) {
   		ServletWebServerFactory factory = getWebServerFactory();
   		this.webServer = factory.getWebServer(getSelfInitializer());
   	}
   	else if (servletContext != null) {
   		try {
   			getSelfInitializer().onStartup(servletContext);
   		}
   		catch (ServletException ex) {
   			throw new ApplicationContextException("Cannot initialize servlet context", ex);
   		}
   	}
   	initPropertySources();
   }

6) ServletWebServerFactory factory = getWebServerFactory();

  • 获取嵌入式servlet容器工厂
  • 从容器中获取ServletWebServerFactory组件
  • TomcatServletWebServerFactory创建对象
  • 后置处理器进行判断,如果是webServerFactory 类对象,获取所有的Customizer【Customizer对象在此创建】,并调用其customize(),完成servlet相关配置
  @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 	//如果是webServerFactory 类对象,获取所有的Customizer
 	if (bean instanceof WebServerFactory) {
 		postProcessBeforeInitialization((WebServerFactory) bean);
 	}
 	return bean;
 }
 private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
 	LambdaSafe.callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory)
 	.withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)
 	.invoke((customizer) -> customizer.customize(webServerFactory));
 }

7) this.webServer = factory.getWebServer(getSelfInitializer());

  • 使用Servlet 容器工厂 获取嵌入式Servlet 容器
  • 嵌入式Servlet 容器 创建对象(此处为tomcat),并启动
public WebServer getWebServer(ServletContextInitializer... initializers) {
      return getTomcatWebServer(tomcat);
  }
  
  protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
  	return new TomcatWebServer(tomcat, getPort() >= 0);
  }
  
  public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
  	Assert.notNull(tomcat, "Tomcat Server must not be null");
  	this.tomcat = tomcat;
  	this.autoStart = autoStart;
  	initialize();
  }
  private void initialize() throws WebServerException {
      this.tomcat.start();
  }

8)先启动嵌入式的Servlet容器,再将Ioc容器中没有创建的对象获取出来

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值