1. 程式人生 > 實用技巧 >Pytest學習(十九)- 報告Environment 不顯示怎麼辦

Pytest學習(十九)- 報告Environment 不顯示怎麼辦

啟動內建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
}