zoukankan      html  css  js  c++  java
  • SpringBoot启动原理

    启动内置Tomcat原理

    从SpringApplication.run进入

    /*
    SpringApplication > run()
    */
    ......
    try {
       ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
       ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
       configureIgnoreBeanInfo(environment);
       Banner printedBanner = printBanner(environment);
        //创建web容器或者普通IOC容器
       context = createApplicationContext();
       exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
             new Class[] { ConfigurableApplicationContext.class }, context);
       prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        //刷新容器
       refreshContext(context);
       afterRefresh(context, applicationArguments);
       stopWatch.stop();
       if (this.logStartupInfo) {
          new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
       }
       listeners.started(context);
       callRunners(context, applicationArguments);
    }
    ......
    

    从refreshContext进入,会一直调到AbstartApplicationContext的refresh()方法

    /*
    AbstartApplicaionContext > refresh()
    */
    ......
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);
    
    // Invoke factory processors registered as beans in the context.
    //注册自定义的beanDefinition,并执行BeanFactory和BeanDefinition后置处理器方法
    //这里会BeanFactory的后置处理器方法,完成springBoot属性自动注入
    invokeBeanFactoryPostProcessors(beanFactory);
    
    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);
    
    // Initialize message source for this context.
    initMessageSource();
    
    // Initialize event multicaster for this context.
    initApplicationEventMulticaster();
    
    // Initialize other special beans in specific context subclasses.
    //本来是一个空方法,但ServletWebServerApplicationContext实现了这个方法,并且在这里完成对Tomcat的启动
    onRefresh();
    
    // Check for listener beans and register them.
    registerListeners();
    
    // Instantiate all remaining (non-lazy-init) singletons.
    //对ben进行初始化
    finishBeanFactoryInitialization(beanFactory);
    
    // Last step: publish corresponding event.
    finishRefresh();
    ......
    

    进入onRefresh方法中

    /*
    ServletWebServerApplicaionContext > onRefresh()
    */
    @Override
    protected void onRefresh() {
       super.onRefresh();
       try {
          createWebServer();
       }
       catch (Throwable ex) {
          throw new ApplicationContextException("Unable to start web server", ex);
       }
    }
    
    /*
    ServletWebServerApplicaionContext > createWebServer()
    */
    private void createWebServer() {
    		WebServer webServer = this.webServer;
    		ServletContext servletContext = getServletContext();
    		if (webServer == null && servletContext == null) {
                //获取对应的webServer工厂,并调用自动装配好的容器自定义定制器
    			ServletWebServerFactory factory = getWebServerFactory();
                //获取Tomcat对象
    			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();
    	}
    

    进入getWebServer方法,完成对内置Tomcat创建和启动

    /*
    TomcatServletWebServletFactory > getWebServer()
    */
    @Override
    	public WebServer getWebServer(ServletContextInitializer... initializers) {
    		if (this.disableMBeanRegistry) {
    			Registry.disableRegistry();
    		}
            //创建Tomcat
    		Tomcat tomcat = new Tomcat();
    		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
            //配置Tomcat
    		tomcat.setBaseDir(baseDir.getAbsolutePath());
    		Connector connector = new Connector(this.protocol);
    		connector.setThrowOnFailure(true);
    		tomcat.getService().addConnector(connector);
    		customizeConnector(connector);
    		tomcat.setConnector(connector);
    		tomcat.getHost().setAutoDeploy(false);
    		configureEngine(tomcat.getEngine());
    		for (Connector additionalConnector : this.additionalTomcatConnectors) {
    			tomcat.getService().addConnector(additionalConnector);
    		}
    		prepareContext(tomcat.getHost(), initializers);
    		return getTomcatWebServer(tomcat);
    	}
    

    从getTomcatWebServer方法进去,最后调用initialize方法完成对Tomcat启动

    /*
    TomcatWebServer > initialize()
    */
    // Start the server to trigger initialization listeners
    //启动Tomcat
    this.tomcat.start();
    
    // We can re-throw failure exception directly in the main thread
    //创建一个守护线程
    rethrowDeferredStartupExceptions();
    
    try {
       ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
    }
    catch (NamingException ex) {
       // Naming is not enabled. Continue
    }
    
  • 相关阅读:
    扩展的局域网
    参数估计
    以太网的 MAC 层
    poj 1523Tarjan算法的含义——求取割点可以分出的连通分量的个数
    tarjan算法--求解无向图的割点和桥
    spfa负环判断
    codeforce 489d bfs分层处理
    并查集优化——压缩路径——秩优化
    SPFA_queue_链式前向星最短路 & HDU2433
    POJ3046选蚂蚁创建集合_线性DP
  • 原文地址:https://www.cnblogs.com/zcr-xiaozhai/p/14057791.html
Copyright © 2011-2022 走看看