玩家必看科普!麻豆人人妻人人妻人人片AV,欧美老妇交乱视频在线观看,久久综合九色综合久99_知乎
<ruby id="fgcka"></ruby>
  • <progress id="fgcka"></progress>
    <tbody id="fgcka"></tbody>
    <dd id="fgcka"></dd>

    1. <dd id="fgcka"></dd>

      <em id="fgcka"></em>
        1. 系統城裝機大師 - 固鎮縣祥瑞電腦科技銷售部宣傳站!

          當前位置:首頁 > 網絡編程 > JavaScript > 詳細頁面

          ServletWebServerApplicationContext創建Web容器Tomcat示例

          時間:2023-03-15來源:系統城裝機大師作者:佚名

          ServletWebServerApplicationContext實現了父類AbstractApplicationContext的onRefresh模板方法,在這里進行了拓展創建了Web容器。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          @Override
          protected void onRefresh() {
             super.onRefresh();
             try {
                createWebServer();
             }
             catch (Throwable ex) {
                throw new ApplicationContextException("Unable to start web server", ex);
             }
          }

          創建Web服務

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          private void createWebServer() {
             WebServer webServer = this.webServer;
             ServletContext servletContext = getServletContext();
             if (webServer == null &amp;&amp; servletContext == null) {
                //一、獲取Web服務器工廠
                ServletWebServerFactory factory = getWebServerFactory();
                //二、獲取Web服務
                this.webServer = factory.getWebServer(getSelfInitializer());
                //三、注冊Bean生命周期(在容器啟動和銷毀時調用)
                getBeanFactory().registerSingleton("webServerGracefulShutdown",
                      new WebServerGracefulShutdownLifecycle(this.webServer));
                getBeanFactory().registerSingleton("webServerStartStop",
                      new WebServerStartStopLifecycle(this, this.webServer));
             }
             else if (servletContext != null) {
                try {
                   getSelfInitializer().onStartup(servletContext);
                }
                catch (ServletException ex) {
                   throw new ApplicationContextException("Cannot initialize servlet context", ex);
                }
             }
             //四、初始化上下文環境
             initPropertySources();
          }

          一、獲取Web服務器工廠

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          protected ServletWebServerFactory getWebServerFactory() {
             // Use bean names so that we don't consider the hierarchy
             //獲取Web服務器工廠名稱
             String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
             if (beanNames.length == 0) {
                throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
                      + "ServletWebServerFactory bean.");
             }
             if (beanNames.length &gt; 1) {
                throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
                      + "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
             }
             //從容器中獲取Web服務器工廠實例
             return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
          }

          這里的Web服務器工廠是通過ServletWebServerFactoryAutoConfiguration自動配置類導入進來的。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          @Configuration(proxyBeanMethods = false)
          @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
          @ConditionalOnClass(ServletRequest.class)
          //Web啟動環境
          @ConditionalOnWebApplication(type = Type.SERVLET)
          @EnableConfigurationProperties(ServerProperties.class)
          //2.1導入Web工廠
          @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
                ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
                ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
                ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
          public class ServletWebServerFactoryAutoConfiguration {
             //導入Web服務器工廠自定義程序
             @Bean
             public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
                return new ServletWebServerFactoryCustomizer(serverProperties);
             }
             //如果是Tomcat則導入Tomcat自定義程序
             @Bean
             @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
             public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
                   ServerProperties serverProperties) {
                return new TomcatServletWebServerFactoryCustomizer(serverProperties);
             }
             @Bean
             @ConditionalOnMissingFilterBean(ForwardedHeaderFilter.class)
             @ConditionalOnProperty(value = "server.forward-headers-strategy", havingValue = "framework")
             public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
                ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
                FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
                registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
                registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
                return registration;
             }
             /**
              * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
              * {@link ImportBeanDefinitionRegistrar} for early registration.
              */
             public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
                private ConfigurableListableBeanFactory beanFactory;
                @Override
                public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
                   if (beanFactory instanceof ConfigurableListableBeanFactory) {
                      this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
                   }
                }
                @Override
                public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                      BeanDefinitionRegistry registry) {
                   if (this.beanFactory == null) {
                      return;
                   }
                   registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor",
                         WebServerFactoryCustomizerBeanPostProcessor.class);
                   registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor",
                         ErrorPageRegistrarBeanPostProcessor.class);
                }
                private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) {
                   if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
                      RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
                      beanDefinition.setSynthetic(true);
                      registry.registerBeanDefinition(name, beanDefinition);
                   }
                }
             }
          }

          1.1 選擇導入Web工廠

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          @Configuration
          class ServletWebServerFactoryConfiguration {
              ServletWebServerFactoryConfiguration() {
              }
              //1.如果容器中有Servlet,Undertow,SslClientAuthMode就會創建Undertow工廠
              @Configuration
              @ConditionalOnClass({Servlet.class, Undertow.class, SslClientAuthMode.class})
              @ConditionalOnMissingBean(
                  value = {ServletWebServerFactory.class},
                  search = SearchStrategy.CURRENT
              )
              public static class EmbeddedUndertow {
                  public EmbeddedUndertow() {
                  }
                  @Bean
                  public UndertowServletWebServerFactory undertowServletWebServerFactory() {
                      return new UndertowServletWebServerFactory();
                  }
              }
              //2.如果容器中有Servlet,Server,Loader就會創建Jetty工廠
              @Configuration
              @ConditionalOnClass({Servlet.class, Server.class, Loader.class, WebAppContext.class})
              @ConditionalOnMissingBean(
                  value = {ServletWebServerFactory.class},
                  search = SearchStrategy.CURRENT
              )
              public static class EmbeddedJetty {
                  public EmbeddedJetty() {
                  }
                  @Bean
                  public JettyServletWebServerFactory JettyServletWebServerFactory() {
                      return new JettyServletWebServerFactory();
                  }
              }
              //3.如果容器中有Servlet,Tomcat,UpgradeProtocol就會創建Tomcat工廠
              @Configuration
              @ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class})
              @ConditionalOnMissingBean(
                  value = {ServletWebServerFactory.class},
                  search = SearchStrategy.CURRENT
              )
              public static class EmbeddedTomcat {
                  public EmbeddedTomcat() {
                  }
                  @Bean
                  public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
                      return new TomcatServletWebServerFactory();
                  }
              }
          }

          二、getWebServer:獲取Web服務

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol";
          private String protocol = DEFAULT_PROTOCOL;
          public WebServer getWebServer(ServletContextInitializer... initializers) {
              Tomcat tomcat = new Tomcat();
              // 給嵌入式Tomcat創建一個臨時文件夾,用于存放Tomcat運行中需要的文件
              File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
              tomcat.setBaseDir(baseDir.getAbsolutePath());
              // Tomcat核心概念:Connector,默認放入的protocol為NIO模式
              Connector connector = new Connector(this.protocol);
              // 給Service添加Connector
              tomcat.getService().addConnector(connector);
              // 執行定制器,修改即將設置到Tomcat中的Connector
              customizeConnector(connector);
              tomcat.setConnector(connector);
              // 關閉熱部署(嵌入式Tomcat不存在修改web.xml、war包等情況)
              tomcat.getHost().setAutoDeploy(false);
              // 設置backgroundProcessorDelay機制
              configureEngine(tomcat.getEngine());
              for (Connector additionalConnector : this.additionalTomcatConnectors) {
                  tomcat.getService().addConnector(additionalConnector);
              }
              // 2.1 創建TomcatEmbeddedContext
              prepareContext(tomcat.getHost(), initializers);
              // 2.2. 創建TomcatWebServer
              return getTomcatWebServer(tomcat);
          }

          2.1 創建TomcatEmbeddedContext

          (注釋均已在源碼中標注好,小伙伴們對哪一步感興趣可以借助IDE自己動手Debug體會一下實現)

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
              File documentRoot = getValidDocumentRoot();
              // 創建TomcatEmbeddedContext
              TomcatEmbeddedContext context = new TomcatEmbeddedContext();
              if (documentRoot != null) {
                  context.setResources(new LoaderHidingResourceRoot(context));
              }
              context.setName(getContextPath());
              context.setDisplayName(getDisplayName());
              // 設置contextPath,很熟悉了
              context.setPath(getContextPath());
              // 給嵌入式Tomcat創建docbase的臨時文件夾
              File docBase = (documentRoot != null) ? documentRoot : createTempDir("tomcat-docbase");
              context.setDocBase(docBase.getAbsolutePath());
              // 注冊監聽器
              context.addLifecycleListener(new FixContextListener());
              context.setParentClassLoader((this.resourceLoader != null) ? this.resourceLoader.getClassLoader()
                      : ClassUtils.getDefaultClassLoader());
              // 設置默認編碼映射
              resetDefaultLocaleMapping(context);
              addLocaleMappings(context);
              context.setUseRelativeRedirects(false);
              try {
                  context.setCreateUploadTargets(true);
              }
              catch (NoSuchMethodError ex) {
                  // Tomcat is &lt; 8.5.39. Continue.
              }
              configureTldSkipPatterns(context);
              // 自定義的類加載器,可以加載web應用的jar包
              WebappLoader loader = new WebappLoader(context.getParentClassLoader());
              loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
              // 指定類加載器遵循雙親委派機制
              loader.setDelegate(true);
              context.setLoader(loader);
              // 注冊默認的Servlet
              if (isRegisterDefaultServlet()) {
                  addDefaultServlet(context);
              }
              // 如果需要jsp支持,注冊jsp的Servlet和Initializer
              if (shouldRegisterJspServlet()) {
                  addJspServlet(context);
                  addJasperInitializer(context);
              }
              // 注冊監聽器
              context.addLifecycleListener(new StaticResourceConfigurer(context));
              ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
              host.addChild(context);
              configureContext(context, initializersToUse);
              postProcessContext(context);
          }

          2.2. 創建TomcatWebServer

          1
          2
          3
          protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
             return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
          }

          進入TomcatWebServer構造方法中:

          1
          2
          3
          4
          5
          6
          7
          public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
              Assert.notNull(tomcat, "Tomcat Server must not be null");
              this.tomcat = tomcat;
              this.autoStart = autoStart;
              //初始化服務
              initialize();
          }

          初始化TomcatWebServer

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          private void initialize() throws WebServerException {
             logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
             synchronized (this.monitor) {
                try {
                   //設置Engine的id
                   addInstanceIdToEngineName();
                   //獲取Context(TomcatEmbeddedContext  2.1中創建出來的)
                   Context context = findContext();
                   //添加監聽器 TomcatEmbeddedContext
                   //在服務啟動時如果有連接進來先刪除連接,以便在啟動服務時不會發生協議綁定。
                   context.addLifecycleListener((event) -> {
                      if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
                         // Remove service connectors so that protocol binding doesn't
                         // happen when the service is started.
                         //刪除ServiceConnectors,以便在啟動服務時不會發生協議綁定。
                         removeServiceConnectors();
                      }
                   });
                   // Start the server to trigger initialization listeners
                   //2.2.1 啟動Tomcat
                   this.tomcat.start();
                   // We can re-throw failure exception directly in the main thread
                   //Tomcat啟動有異常需要在主線程中拋出
                   rethrowDeferredStartupExceptions();
                   try {
                      ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
                   }
                   catch (NamingException ex) {
                      // Naming is not enabled. Continue
                   }
                   // Unlike Jetty, all Tomcat threads are daemon threads. We create a
                   // blocking non-daemon to stop immediate shutdown
                   //開啟阻塞非守護線程停止web容器
                   startDaemonAwaitThread();
                }
                catch (Exception ex) {
                   stopSilently();
                   destroySilently();
                   throw new WebServerException("Unable to start embedded Tomcat", ex);
                }
             }
          }

          2.2.1 啟動Tomcat

          創建和初始化Server和Service

          1
          2
          3
          4
          5
          public void start() throws LifecycleException {
              //創建服務(Server和Service)
              getServer();
              server.start();
          }

          啟動服務

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          public final synchronized void start() throws LifecycleException {
              //如果是正在啟動或啟動狀態
              if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                      LifecycleState.STARTED.equals(state)) {
                  if (log.isDebugEnabled()) {
                      Exception e = new LifecycleException();
                      log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
                  } else if (log.isInfoEnabled()) {
                      log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
                  }
                  return;
              }
              //如果是新建狀態
              if (state.equals(LifecycleState.NEW)) {
                  //2.2.1.1 初始化服務
                  init();
              //如果是失敗狀態   
              } else if (state.equals(LifecycleState.FAILED)) {
                  //停止服務
                  stop();
              //如果不是初始化也不是停止狀態
              } else if (!state.equals(LifecycleState.INITIALIZED) &amp;&amp;
                      !state.equals(LifecycleState.STOPPED)) {
                  //修改狀態
                  invalidTransition(Lifecycle.BEFORE_START_EVENT);
              }
              try {
                  //修改狀態為準備啟動
                  setStateInternal(LifecycleState.STARTING_PREP, null, false);
                  //2.2.1.2 啟動Internal
                  startInternal();
                  if (state.equals(LifecycleState.FAILED)) {
                      // This is a 'controlled' failure. The component put itself into the
                      // FAILED state so call stop() to complete the clean-up.
                      stop();
                  } else if (!state.equals(LifecycleState.STARTING)) {
                      // Shouldn't be necessary but acts as a check that sub-classes are
                      // doing what they are supposed to.
                      invalidTransition(Lifecycle.AFTER_START_EVENT);
                  } else {
                      setStateInternal(LifecycleState.STARTED, null, false);
                  }
              } catch (Throwable t) {
                  // This is an 'uncontrolled' failure so put the component into the
                  // FAILED state and throw an exception.
                  handleSubClassException(t, "lifecycleBase.startFail", toString());
              }
          }

          2.2.1.1 初始化Server

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          public final synchronized void init() throws LifecycleException {
              if (!state.equals(LifecycleState.NEW)) {
                  invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
              }
              try {
                  //設置狀態為初始化
                  setStateInternal(LifecycleState.INITIALIZING, null, false);
                  //初始化
                  initInternal();
                  //設置狀態為初始化完成
                  setStateInternal(LifecycleState.INITIALIZED, null, false);
              } catch (Throwable t) {
                  handleSubClassException(t, "lifecycleBase.initFail", toString());
              }
          }

          初始化 Server

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          protected void initInternal() throws LifecycleException {
              //調用父類初始化(設置名稱:Tomcat,類型:Server)
              super.initInternal();
              // Initialize utility executor
              reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
              //注冊線程池
              register(utilityExecutor, "type=UtilityExecutor");
              // Register global String cache
              // Note although the cache is global, if there are multiple Servers
              // present in the JVM (may happen when embedding) then the same cache
              // will be registered under multiple names
              //注冊字符串緩存
              onameStringCache = register(new StringCache(), "type=StringCache");
              // Register the MBeanFactory
              MBeanFactory factory = new MBeanFactory();
              factory.setContainer(this);
              //注冊Bean工廠
              onameMBeanFactory = register(factory, "type=MBeanFactory");
              // Register the naming resources
              //注冊命名資源
              globalNamingResources.init();
              // Populate the extension validator with JARs from common and shared
              // class loaders
              if (getCatalina() != null) {
                  ClassLoader cl = getCatalina().getParentClassLoader();
                  // Walk the class loader hierarchy. Stop at the system class loader.
                  // This will add the shared (if present) and common class loaders
                  while (cl != null &amp;&amp; cl != ClassLoader.getSystemClassLoader()) {
                      if (cl instanceof URLClassLoader) {
                          URL[] urls = ((URLClassLoader) cl).getURLs();
                          for (URL url : urls) {
                              if (url.getProtocol().equals("file")) {
                                  try {
                                      File f = new File (url.toURI());
                                      if (f.isFile() &amp;&amp;
                                              f.getName().endsWith(".jar")) {
                                          ExtensionValidator.addSystemResource(f);
                                      }
                                  } catch (URISyntaxException e) {
                                      // Ignore
                                  } catch (IOException e) {
                                      // Ignore
                                  }
                              }
                          }
                      }
                      cl = cl.getParent();
                  }
              }
              // Initialize our defined Services
              //2.2.1.1.1 初始化service(2.2.1最開始時創建)
              for (Service service : services) {
                  service.init();
              }
          }

          初始化Service

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          public final synchronized void init() throws LifecycleException {
              if (!state.equals(LifecycleState.NEW)) {
                  invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
              }
              try {
                  //設置狀態為初始化
                  setStateInternal(LifecycleState.INITIALIZING, null, false);
                  //初始化
                  initInternal();
                  //設置狀態為初始化完成
                  setStateInternal(LifecycleState.INITIALIZED, null, false);
              } catch (Throwable t) {
                  handleSubClassException(t, "lifecycleBase.initFail", toString());
              }
          }

          初始化Service

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          protected void initInternal() throws LifecycleException {
              //調用父類初始化(設置名稱:Tomcat,類型:Server)
              super.initInternal();
              //2.2.1.1.1.1 初始化engine
              if (engine != null) {
                  engine.init();
              }
              // Initialize any Executors
              //2.2.1.1.1.2 初始化executor
              for (Executor executor : findExecutors()) {
                  if (executor instanceof JmxEnabled) {
                      ((JmxEnabled) executor).setDomain(getDomain());
                  }
                  executor.init();
              }
              // Initialize mapper listener
              //2.2.1.1.1.3 初始化mapperListener
              mapperListener.init();
              // Initialize our defined Connectors
              //2.2.1.1.1.4 初始化connector
              synchronized (connectorsLock) {
                  for (Connector connector : connectors) {
                      connector.init();
                  }
              }
          }

          初始化engine

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          protected void initInternal() throws LifecycleException {
              // Ensure that a Realm is present before any attempt is made to start
              // one. This will create the default NullRealm if necessary.
              // 在嘗試啟動一個Realm之前,請確保存在一個Realm。如有必要,這將創建默認的NullRealm
              getRealm();
              super.initInternal();
          }
          public Realm getRealm() {
              Realm configured = super.getRealm();
              // If no set realm has been called - default to NullRealm
              // This can be overridden at engine, context and host level
              if (configured == null) {
                  configured = new NullRealm();
                  this.setRealm(configured);
              }
              return configured;
          }

          初始化executor

          它還是調的父類 LifecycleMBeanBase 的方法

          1
          2
          3
          protected void initInternal() throws LifecycleException {
              super.initInternal();
          }

          初始化mapperListener

          1
          2
          3
          4
          5
          6
          7
          8
          protected void initInternal() throws LifecycleException {
              // If oname is not null then registration has already happened via preRegister().
              // 如果oname不為null,則已經通過preRegister()進行了注冊
              if (oname == null) {
                  mserver = Registry.getRegistry(null, null).getMBeanServer();
                  oname = register(this, getObjectNameKeyProperties());
              }
          }

          初始化connector

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          protected void initInternal() throws LifecycleException {
              super.initInternal();
              if (protocolHandler == null) {
                  throw new LifecycleException(
                          sm.getString("coyoteConnector.protocolHandlerInstantiationFailed"));
              }
              // Initialize adapter
              adapter = new CoyoteAdapter(this);
              protocolHandler.setAdapter(adapter);
              if (service != null) {
                  protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
              }
              // Make sure parseBodyMethodsSet has a default
              if (null == parseBodyMethodsSet) {
                  setParseBodyMethods(getParseBodyMethods());
              }
              if (protocolHandler.isAprRequired() &amp;&amp; !AprStatus.isInstanceCreated()) {
                  throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener",
                          getProtocolHandlerClassName()));
              }
              if (protocolHandler.isAprRequired() &amp;&amp; !AprStatus.isAprAvailable()) {
                  throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary",
                          getProtocolHandlerClassName()));
              }
              if (AprStatus.isAprAvailable() &amp;&amp; AprStatus.getUseOpenSSL() &amp;&amp;
                      protocolHandler instanceof AbstractHttp11JsseProtocol) {
                  AbstractHttp11JsseProtocol&lt;?&gt; jsseProtocolHandler =
                          (AbstractHttp11JsseProtocol&lt;?&gt;) protocolHandler;
                  if (jsseProtocolHandler.isSSLEnabled() &amp;&amp;
                          jsseProtocolHandler.getSslImplementationName() == null) {
                      // OpenSSL is compatible with the JSSE configuration, so use it if APR is available
                      jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
                  }
              }
              try {
                  //2.2.1.1.1.5 初始化protocolHandler
                  protocolHandler.init();
              } catch (Exception e) {
                  throw new LifecycleException(
                          sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
              }
          }

          初始化protocolHandler

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          public void init() throws Exception {
              // Upgrade protocols have to be configured first since the endpoint
              // init (triggered via super.init() below) uses this list to configure
              // the list of ALPN protocols to advertise
              // 必須先配置升級協議,因為端點初始化(通過下面的super.init()觸發)使用此列表來配置要發布的ALPN協議列表
              for (UpgradeProtocol upgradeProtocol : upgradeProtocols) {
                  configureUpgradeProtocol(upgradeProtocol);
              }
              super.init();
          }

          Debug發現這個 upgradeProtocols 為空,直接走下面父類(AbstractProtocol)的 init 方法:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          public void init() throws Exception {
              if (getLog().isInfoEnabled()) {
                  getLog().info(sm.getString("abstractProtocolHandler.init", getName()));
                  logPortOffset();
              }
              if (oname == null) {
                  // Component not pre-registered so register it
                  oname = createObjectName();
                  if (oname != null) {
                      Registry.getRegistry(null, null).registerComponent(this, oname, null);
                  }
              }
              if (this.domain != null) {
                  rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName());
                  Registry.getRegistry(null, null).registerComponent(
                          getHandler().getGlobal(), rgOname, null);
              }
              String endpointName = getName();
              endpoint.setName(endpointName.substring(1, endpointName.length()-1));
              endpoint.setDomain(domain);
              //2.2.1.1.1.6 初始化endpoint
              endpoint.init();
          }

          上面又是一堆初始化,這個咱暫且不關注,注意最底下有一個 endpoint.init :

          初始化endpoint

          來到 AbstractEndPoint :

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          public final void init() throws Exception {
              // Debug為false
              if (bindOnInit) {
                  bindWithCleanup();
                  bindState = BindState.BOUND_ON_INIT;
              }
              if (this.domain != null) {
                  // Register endpoint (as ThreadPool - historical name)
                  oname = new ObjectName(domain + ":type=ThreadPool,name="" + getName() + """);
                  Registry.getRegistry(null, null).registerComponent(this, oname, null);
                  ObjectName socketPropertiesOname = new ObjectName(domain +
                          ":type=ThreadPool,name="" + getName() + "",subType=SocketProperties");
                  socketProperties.setObjectName(socketPropertiesOname);
                  Registry.getRegistry(null, null).registerComponent(socketProperties, socketPropertiesOname, null);
                  for (SSLHostConfig sslHostConfig : findSslHostConfigs()) {
                      registerJmx(sslHostConfig);
                  }
              }
          }

          這里面又是初始化 oname ,又是配置 socketProperties 的,但這里面再也沒見到 init 方法,證明這部分初始化過程已經結束了。

           初始化小結

          嵌入式 Tomcat 的組件初始化步驟順序如下:

          • Server
          • Service
          • Engine
          • Executor
          • MapperListener
          • Connector
          • Protocol
          • EndPoint

          startInternal:啟動Internal

          startInternal 方法中有兩部分啟動:globalNamingResources 啟動,services 啟動。分別來看:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          protected void startInternal() throws LifecycleException {
              // 發布啟動事件
              fireLifecycleEvent(CONFIGURE_START_EVENT, null);
              setState(LifecycleState.STARTING);
              // 2.2.1.2.1 NamingResources啟動
              globalNamingResources.start();
              // Start our defined Services
              synchronized (servicesLock) {
                  for (int i = 0; i &lt; services.length; i++) {
                      // 2.2.1.2.2 Service啟動
                      services[i].start();
                  }
              }
              if (periodicEventDelay &gt; 0) {
                  monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
                          new Runnable() {
                              @Override
                              public void run() {
                                  startPeriodicLifecycleEvent();
                              }
                          }, 0, 60, TimeUnit.SECONDS);
              }
          }

          NamingResources啟動

          只是發布事件和設置狀態而已

          1
          2
          3
          4
          protected void startInternal() throws LifecycleException {
              fireLifecycleEvent(CONFIGURE_START_EVENT, null);
              setState(LifecycleState.STARTING);
          }

          Service啟動

          依次啟動 Engine 、Executor 、MapperListener 、Connector 

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          protected void startInternal() throws LifecycleException {
              if(log.isInfoEnabled())
                  log.info(sm.getString("standardService.start.name", this.name));
              setState(LifecycleState.STARTING);
              // Start our defined Container first
              if (engine != null) {
                  synchronized (engine) {
                      // 2.2.1.2.2.1 啟動Engine
                      engine.start();
                  }
              }
              synchronized (executors) {
                  for (Executor executor: executors) {
                      // 2.2.1.2.2.3 啟動Executor
                      executor.start();
                  }
              }
              // 2.2.1.2.2.4 啟動MapperListener
              mapperListener.start();
              // Start our defined Connectors second
              synchronized (connectorsLock) {
                  for (Connector connector: connectors) {
                      // If it has already failed, don't try and start it
                      if (connector.getState() != LifecycleState.FAILED) {
                          // 2.2.1.2.2.5 啟動connector
                          connector.start();
                      }
                  }
              }
          }

          啟動Engine

          1
          2
          3
          4
          5
          6
          7
          8
          protected synchronized void startInternal() throws LifecycleException {
              // Log our server identification information
              if (log.isInfoEnabled()) {
                  log.info(sm.getString("standardEngine.start", ServerInfo.getServerInfo()));
              }
              // Standard container startup
              super.startInternal();
          }

          它直接調的父類 ContainerBase 的 startInternal 方法:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          protected synchronized void startInternal() throws LifecycleException {
              // Start our subordinate components, if any
              logger = null;
              getLogger();
              // Cluster與集群相關,SpringBoot項目中使用嵌入式Tomcat,不存在集群
              Cluster cluster = getClusterInternal();
              if (cluster instanceof Lifecycle) {
                  ((Lifecycle) cluster).start();
              }
              // Realm與授權相關
              Realm realm = getRealmInternal();
              if (realm instanceof Lifecycle) {
                  ((Lifecycle) realm).start();
              }
              // Start our child containers, if any
              // Container的類型是StandardHost
              Container children[] = findChildren();
              List&lt;Future&lt;Void&gt;&gt; results = new ArrayList&lt;&gt;();
              for (int i = 0; i &lt; children.length; i++) {
                  //異步初始化Host
                  results.add(startStopExecutor.submit(new StartChild(children[i])));
              }
              MultiThrowable multiThrowable = null;
              for (Future&lt;Void&gt; result : results) {
                  try {
                      result.get();
                  } catch (Throwable e) {
                      log.error(sm.getString("containerBase.threadedStartFailed"), e);
                      if (multiThrowable == null) {
                          multiThrowable = new MultiThrowable();
                      }
                      multiThrowable.add(e);
                  }
              }
              if (multiThrowable != null) {
                  throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
                          multiThrowable.getThrowable());
              }
              // Start the Valves in our pipeline (including the basic), if any
              if (pipeline instanceof Lifecycle) {
                  ((Lifecycle) pipeline).start();
              }
              setState(LifecycleState.STARTING);
              // Start our thread
              if (backgroundProcessorDelay &gt; 0) {
                  monitorFuture = Container.getService(ContainerBase.this).getServer()
                          .getUtilityExecutor().scheduleWithFixedDelay(
                                  new ContainerBackgroundProcessorMonitor(), 0, 60, TimeUnit.SECONDS);
              }
          }

          StartChild 實現了帶返回值的異步多線程接口 Callable 核心方法就是在 call

          1 private static class StartChild implements Callable<Void>

          它實現了帶返回值的異步多線程接口 Callable !那里面的核心方法就是 call :

          1
          2
          3
          4
          public Void call() throws LifecycleException {
              child.start();
              return null;
          }

          它在這里初始化 child,而通過Debug得知 child 的類型是 StandardHost,故來到 StandardHost 的 start 方法:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          protected synchronized void startInternal() throws LifecycleException {
              // Set error report valve
              String errorValve = getErrorReportValveClass();
              if ((errorValve != null) &amp;&amp; (!errorValve.equals(""))) {
                  try {
                      boolean found = false;
                      Valve[] valves = getPipeline().getValves();
                      for (Valve valve : valves) {
                          if (errorValve.equals(valve.getClass().getName())) {
                              found = true;
                              break;
                          }
                      }
                      if(!found) {
                          Valve valve =
                              (Valve) Class.forName(errorValve).getConstructor().newInstance();
                          getPipeline().addValve(valve);
                      }
                  } catch (Throwable t) {
                      ExceptionUtils.handleThrowable(t);
                      log.error(sm.getString(
                              "standardHost.invalidErrorReportValveClass",
                              errorValve), t);
                  }
              }
              super.startInternal();
          }

          上面的一個大if結構是設置錯誤提示頁面的,下面又調父類的 startInternal :

          1
          2
          3
          4
          5
          6
          7
          8
          protected synchronized void startInternal() throws LifecycleException {
              // ......
              // Start our child containers, if any
              Container children[] = findChildren();
              List<Future<Void>> results = new ArrayList<>();
              for (int i = 0; i < children.length; i++) {
                  results.add(startStopExecutor.submit(new StartChild(children[i])));
              }

          又回來了。。。因為一個 Host 包含一個 Context 。

          Host 搜索children就會搜到它下面的 Context ,之后又是下面的初始化過程,進入 Context 的初始化:

           啟動TomcatEmbeddedContext

          在TomcatEmbeddedContext有如下組件被調用了 start 方法:

          • StandardRoot
          • DirResourceSet
          • WebappLoader
          • JarResourceSet
          • StandardWrapper
          • StandardPineline
          • StandardWrapperValve
          • NonLoginAuthenticator
          • StandardContextValve
          • StandardManager
          • LazySessionIdGenerator

          啟動Executor

          但由于 Executor 沒有實現 startInternal 方法,所以不會啟動

          1
          2
          3
          4
          5
          synchronized (executors) {
              for (Executor executor: executors) {
                  executor.start();
              }
          }

          啟動MapperListener

          接下來啟動 MapperListener :

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          public void startInternal() throws LifecycleException {
              setState(LifecycleState.STARTING);
              Engine engine = service.getContainer();
              if (engine == null) {
                  return;
              }
              // 獲取當前部署的主機名(本地調試為localhost)
              findDefaultHost();
              // 把當前自身注冊到Engine、Host、Context、Wrapper中
              addListeners(engine);
              // 取出的Container的類型為Host
              Container[] conHosts = engine.findChildren();
              for (Container conHost : conHosts) {
                  Host host = (Host) conHost;
                  if (!LifecycleState.NEW.equals(host.getState())) {
                      // Registering the host will register the context and wrappers
                      //將Host、Context、Wrapper注冊到當前監聽器中
                      registerHost(host);
                  }
              }
          }

           啟動Connector

          最后一步是啟動 Connector 。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          // Start our defined Connectors second
          synchronized (connectorsLock) {
              for (Connector connector: connectors) {
                  // If it has already failed, don't try and start it
                  if (connector.getState() != LifecycleState.FAILED) {
                      connector.start();
                  }
              }
          }

           啟動總結

          啟動過程依次啟動了如下組件:

          • NamingResources
          • Service
          • Engine
          • Host
          • Context
          • Wrapper
          • Executor
          • MapperListener

          三、注冊Bean生命周期

          3.1 WebServerStartStopLifecycle(Web服務器啟動-停止生命周期)

          WebServerStartStopLifecycle實現了Lifecycle,在容器刷新完成時會調用finishRefresh()

          1
          2
          3
          4
          5
          6
          7
          8
          @Override
          public void start() {
             //啟動Tomcat 容器
             this.webServer.start();
             this.running = true;
             this.applicationContext
                   .publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          public void start() throws WebServerException {
              synchronized (this.monitor) {
                  if (this.started) {
                      return;
                  }
                  try {
                      // 3.1.1 還原、啟動Connector
                      addPreviouslyRemovedConnectors();
                      // 只拿一個Connector
                      Connector connector = this.tomcat.getConnector();
                      if (connector != null &amp;&amp; this.autoStart) {
                          // 3.1.2 延遲啟動
                          performDeferredLoadOnStartup();
                      }
                      // 檢查Connector是否正常啟動
                      checkThatConnectorsHaveStarted();
                      this.started = true;
                      logger.info("Tomcat started on port(s): " + getPortsDescription(true) + " with context path '"
                              + getContextPath() + "'");
                  }
                  // catch ......
                  finally {
                      // 解除ClassLoader與TomcatEmbeddedContext的綁定關系
                      Context context = findContext();
                      ContextBindings.unbindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
                  }
              }
          }

          3.1.1 addPreviouslyRemovedConnectors:啟動Connector

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          private void addPreviouslyRemovedConnectors() {
              Service[] services = this.tomcat.getServer().findServices();
              for (Service service : services) {
                  Connector[] connectors = this.serviceConnectors.get(service);
                  if (connectors != null) {
                      for (Connector connector : connectors) {
                          // 添加并啟動
                          service.addConnector(connector);
                          if (!this.autoStart) {
                              stopProtocolHandler(connector);
                          }
                      }
                      this.serviceConnectors.remove(service);
                  }
              }
          }

          可以發現它將一個緩存區的 Connector 一個一個取出放入 Service 中。注意在 service.addConnector 中有順便啟動的部分:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          public void addConnector(Connector connector) {
              synchronized (connectorsLock) {
                  connector.setService(this);
                  Connector results[] = new Connector[connectors.length + 1];
                  System.arraycopy(connectors, 0, results, 0, connectors.length);
                  results[connectors.length] = connector;
                  connectors = results;
              }
              try {
                  if (getState().isAvailable()) {
                      // 啟動Connector
                      connector.start();
                  }
              } catch (LifecycleException e) {
                  throw new IllegalArgumentException(
                          sm.getString("standardService.connector.startFailed", connector), e);
              }
              // Report this property change to interested listeners
              support.firePropertyChange("connector", null, connector);
          }

          前面的部分是取出 Connector ,并與 Service 綁定,之后中間部分的try塊,會啟動 Connector :

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          protected void startInternal() throws LifecycleException {
              // Validate settings before starting
              if (getPortWithOffset() &lt; 0) {
                  throw new LifecycleException(sm.getString(
                          "coyoteConnector.invalidPort", Integer.valueOf(getPortWithOffset())));
              }
              setState(LifecycleState.STARTING);
              try {
                  // 啟動ProtocolHandler
                  protocolHandler.start();
              } catch (Exception e) {
                  throw new LifecycleException(
                          sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
              }
          }

          Connector 的啟動會引發 ProtocolHandler 的啟動:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          public void start() throws Exception {
              if (getLog().isInfoEnabled()) {
                  getLog().info(sm.getString("abstractProtocolHandler.start", getName()));
                  logPortOffset();
              }
              // 啟動EndPoint
              endpoint.start();
              monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
                      new Runnable() {
                          @Override
                          public void run() {
                              if (!isPaused()) {
                                  startAsyncTimeout();
                              }
                          }
                      }, 0, 60, TimeUnit.SECONDS);
          }

          ProtocolHandler 的啟動會引發 EndPoint 的啟動,至此所有組件均已啟動完畢。

           performDeferredLoadOnStartup:延遲啟動

          這里面會延遲啟動 TomcatEmbeddedContext

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          private void performDeferredLoadOnStartup() {
              try {
                  for (Container child : this.tomcat.getHost().findChildren()) {
                      if (child instanceof TomcatEmbeddedContext) {
                          // 延遲啟動Context
                          ((TomcatEmbeddedContext) child).deferredLoadOnStartup();
                      }
                  }
              }
              catch (Exception ex) {
                  if (ex instanceof WebServerException) {
                      throw (WebServerException) ex;
                  }
                  throw new WebServerException("Unable to start embedded Tomcat connectors", ex);
              }
          }

          四、初始化上下文環境

          這里在Spring中已經刷新過一次,詳情:在文章 https://www.jb51.net/article/277946.htm 的 prepareRefresh:初始化前的預處理中

          分享到:

          相關信息

          系統教程欄目

          欄目熱門教程

          人氣教程排行

          站長推薦

          熱門系統下載

          玩家必看科普!麻豆人人妻人人妻人人片AV,欧美老妇交乱视频在线观看,久久综合九色综合久99_知乎 人人玩人人添人人澡超碰偷拍 青春娱乐视频精品分类官网2 最好最新高清中文字幕 91国自产拍最新2018 欧美精品一区二区三区不卡网 深夜你懂得我的意思2021 宿舍NP乖把腿张开H 网恋奔现一天被要几次 为什么我越叫他越快 学渣各种各样的PLAY 英语课代表下面好软小说 亚洲国产综合在线区尤物 FREE性丰满HD性欧美 我年轻漂亮的继坶BD 最近中文字幕完整免费视频 啦啦啦免费视频卡一卡二 青柠视频在线观看大全 在线天堂WWW在线资源 亚洲国产日本韩国欧美MV 天天学习|久久久久久久精品国产亚洲87 国产K频道分享系统进入口 三个嘴都吃满了还塞满了 JAPONENSIS老师学生JAVAHBB 亚洲精品1卡2卡3卡4卡 樱花草在线社区WWW韩国 好涨水快流出来了快吃动视频 久久AV无码精品人妻出轨