2021年3月31日星期三

SpringBoot内嵌Tomcat启动原理

SpringBoot应用启动运行run方法,然后一直来到这个Run方法public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting(); Collection exceptionReporters; try {  ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);  ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);  this.configureIgnoreBeanInfo(environment);  Banner printedBanner = this.printBanner(environment);  context = this.createApplicationContext();//创建Springboot应用程序(即ApplicationContext),根据环境创建的  exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);  this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);  this.refreshContext(context);//刷新IOC容器,即创建IOC容器对象,并初始化容器,创建容器中的每一个组件(即Bean)  this.afterRefresh(context, applicationArguments);  stopWatch.stop();protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) {  try {   switch(this.webApplicationType) {   case SERVLET://如果是Srevlet环境就创建Servlet的SpringBoot应用    contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");    break;   case REACTIVE:    contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");    break;   default:    contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");   }  } catch (ClassNotFoundException var3) {   throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);  } } return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);}public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; 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();//web的ioc容器重写了onRefresh方法   this.registerListeners();   this.finishBeanFactoryInitialization(beanFactory);   this.finishRefresh();protected void onRefresh() { super.onRefresh(); try {  this.createWebServer();//创建嵌入式的Servlet容器,不过是先获取容器工厂,再创建容器 } catch (Throwable var2) {  throw new ApplicationContextException("Unable to start web server", var2); }}private void createWebServer() { WebServer webServer = this.webServer; ServletContext servletContext = this.getServletContext(); if (webServer == null && servletContext == null) {  ServletWebServerFactory factory = this.getWebServerFactory();//先获取工厂从ioc容器中获取TomcatServletWebServerFactory 组件(是一个bean来的)   通过这个TomcatServletWebServerFactory创建Tomcat对象,后置处理器一看是这个对象,就获取所有的定制器来先定制Servlet容器的相关配置;  this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});//再获取容器 } else if (servletContext != null) {  try {   this.getSelfInitializer().onStartup(servletContext);  } catch (ServletException var4) {   throw new ApplicationContextException("Cannot initialize servlet context", var4);  } } this.initPropertySources();}public WebServer getWebServer(ServletContextInitializer... initializers) { if (this.disableMBeanRegistry) {  Registry.disableRegistry(); } Tomcat tomcat = new Tomcat(); File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); connector.setThrowOnFailure(true); tomcat.getService().addConnector(connector); this.customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); this.configureEngine(tomcat.getEngine()); Iterator var5 = this.additionalTomcatConnectors.iterator(); while(var5.hasNext()) {  Connector additionalConnector = (Connector)var5.next();  tomcat.getService().addConnector(additionalConnector); } this.prepareContext(tomcat.getHost(), initializers); return this.getTomcatWebServer(tomcat);}protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { return new TomcatWebServer(tomcat, this.getPort() >= 0);//端口号大于0就自动启动}public TomcatWebServer(Tomcat tomcat, boolean autoStart) { this.monitor = new Object(); this.serviceConnectors = new HashMap(); Assert.notNull(tomcat, "Tomcat Server must not be null"); this.tomcat = tomcat; this.autoStart = autoStart; this.initialize();//启动}嵌入式的Servlet容器创建对象并启动Servlet容器;TomcatServletWebServerFactory是在ServletWebServerFactoryConfiguration被加入进容器的注入之后在ServletWebServerFactoryAutoConfiguration被导入

@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,  ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,//导入这个class对象  ServletWebServerFactoryConfiguration.EmbeddedJetty.class,  ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })第二步@Configuration(proxyBeanMethods = false)//判断是否导入了Tomcat依赖,导入了就把TomcatServletWebServerFactory放入ioc容器@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)static class EmbeddedTomcat { @Bean TomcatServletWebServerFactory tomcatServletWebServerFactory(   ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,   ObjectProvider<TomcatContextCustomizer> contextCustomizers,   ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {  TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();  factory.getTomcatConnectorCustomizers()   .addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));  factory.getTomcatContextCustomizers()   .addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));  factory.getTomcatProtocolHandlerCustomizers()   .addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));  return factory; }}第三步public WebServer getWebServer(ServletContextInitializer... initializers) { if (this.disableMBeanRegistry) {  Registry.disableRegistry(); } Tomcat tomcat = new Tomcat();//获取Tomcat //配置Tomcat基本环节 File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); connector.setThrowOnFailure(true); tomcat.getService().addConnector(connector); this.customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); this.configureEngine(tomcat.getEngine()); Iterator var5 = this.additionalTomcatConnectors.iterator(); while(var5.hasNext()) {  Connector additionalConnector = (Connector)var5.next();  tomcat.getService().addConnector(additionalConnector); } this.prepareContext(tomcat.getHost(), initializers); return this.getTomcatWebServer(tomcat);//开始启动Tomcat}第四步protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { return new TomcatWebServer(tomcat, this.getPort() >= 0);//端口大于0就自动启动}第五步public TomcatWebServer(Tomcat tomcat, boolean autoStart) { this.monitor = new Object(); this.serviceConnectors = new HashMap(); Assert.notNull(tomcat, "Tomcat Server must not be null"); this.tomcat = tomcat; this.autoStart = autoStart; this.initialize();//准备启动}第六步private void initialize() throws WebServerException { logger.info("Tomcat initialized with port(s): " + this.getPortsDescription(false)); Object var1 = this.monitor; synchronized(this.monitor) {  try {   this.addInstanceIdToEngineName();   Context context = this.findContext();   context.addLifecycleListener((event) -> {    if (context.equals(event.getSource()) && "start".equals(event.getType())) {     this.removeServiceConnectors();    }   });   this.tomcat.start();//启动tomcat  }@Bean//如果classpath有Tomcat就把TomcatServletWebServerFactoryCustomizer放入容器@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(  ServerProperties serverProperties) { return new TomcatServletWebServerFactoryCustomizer(serverProperties);}

 









原文转载:http://www.shaoqun.com/a/656723.html

跨境电商:https://www.ikjzd.com/

parser:https://www.ikjzd.com/w/680

kili:https://www.ikjzd.com/w/238


SpringBoot应用启动运行run方法,然后一直来到这个Run方法publicConfigurableApplicationContextrun(String...args){StopWatchstopWatch=newStopWatch();stopWatch.start();ConfigurableApplicationContextcontext=null;Collection<S
blackbird:https://www.ikjzd.com/w/950
黄远:https://www.ikjzd.com/w/1785
naning9韩国官网:https://www.ikjzd.com/w/2401
mile:https://www.ikjzd.com/w/1746
致新卖家-该如何努力,才能做好亚马逊?:https://www.ikjzd.com/home/19446
穿丝袜太性感 老公骂我像妓女:http://lady.shaoqun.com/m/a/271342.html

没有评论:

发表评论