欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

在Springboot項目中內(nèi)嵌Tomcat時如何使用start

這篇文章給大家介紹在Springboot項目中內(nèi)嵌Tomcat時如何使用start,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:主機域名、網(wǎng)絡(luò)空間、營銷軟件、網(wǎng)站建設(shè)、申扎網(wǎng)站維護、網(wǎng)站推廣。

從TomcatEmbeddedServletContainer的this.tomcat.start()開始,主要是利用LifecycleBase對這一套容器(engine,host,context及wrapper)進行啟動并發(fā)布諸如configure_start、before_init、after_start的lifecycleEvent事件給相應(yīng)的監(jiān)聽器(如果有的話)。進入start,因為此時狀態(tài)是LifecycleState.NEW,所以會執(zhí)行init方法:

 public final synchronized void init() throws LifecycleException {
  if(!this.state.equals(LifecycleState.NEW)) {
   this.invalidTransition("before_init");
  }
  try {
   this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);
   this.initInternal();
   this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false);
  } catch (Throwable var2) {
   ExceptionUtils.handleThrowable(var2);
   this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
   throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2);
  }
 }

   首先,狀態(tài)變?yōu)長ifecycleState.INITIALIZING并發(fā)布一個before_init的LifecycleEvent給所有l(wèi)ifecycleListeners:

這里的super:

因為上面是server.start調(diào)用的start方法,所以雖然方法的代碼在LifecycleBase中,但this指的是StandardServer的實例,于是這里的this.initInternal走的是StandardServer的initInternal方法,initInternal首先調(diào)用了super.initInternal,這里的super是LifecycleMBeanBase,MBean是用于JMX的能代表管理資源的管理構(gòu)件,JMX定義了四種管理構(gòu)件:標準、動態(tài)、開放和模型管理構(gòu)件。每一種管理構(gòu)件可以根據(jù)不同的環(huán)境需要進行制定,檢查標準管理構(gòu)件接口和應(yīng)用設(shè)計模式的過程被稱為內(nèi)省(Introspection),動態(tài)管理構(gòu)件提供了更大的靈活性,它可以在運行期暴露自己的管理接口。它的實現(xiàn)是通過實現(xiàn)一個特定的接口DynamicMBean。MBeanFactoryInitializer初始化是在BackgroundPreinitializer的onApplicationEvent。MBean功能相當強大,例如可以提供服務(wù)器的遠程管理,當然也可以自定義此類功能: 

onameStringCache = register(new StringCache(), "type=StringCache")注冊全局字符串緩存,這里是使用DynamicMBean的方式,注冊后StringCache也提供了類似上圖的被管理功能,可以遠程清楚服務(wù)器的字符串緩存等。 下一句globalNamingResources.init()同樣的LifecycleBase的init套路,先是setStateInternal更新globalNamingResources的LifecycleState狀態(tài)為INITIALIZING發(fā)布before_init事件,然后NamingResourcesImpl的initInternal,里面依然是之前的super.initInternal(),顯示注冊ContextResource、ContextEnvironment、ContextResourceLink避免注冊時序問題,重復注冊沒關(guān)系;又是一個globalNamingResources的LifecycleBase的setStateInternal方法,更新LifecycleState狀態(tài)為INITIALIZED發(fā)布after_init事件;然后回到StandardServer的initInternal,循環(huán)init之前add給server的service:

又是的LifecycleBase的init,只不過這次是StandardService[Tomcat],更新的LifecycleState狀態(tài)為INITIALIZING發(fā)布before_init事件,StandardService的initInternal,super之后是engine.init,同樣engine現(xiàn)在也是初始化階段,更新狀態(tài)發(fā)布事件,然后進入StandardEngine的initInternal:

 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.
  getRealm();
  super.initInternal();
 }

Realm是關(guān)于權(quán)限的,具體可以看http://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html;super(ContainerBase).initInternal創(chuàng)建了一個線程池startStopExecutor,這個startStopExecutor之后會接受兩種任務(wù)StartChild和StopChild用池線程啟動和停止子容器,StartStopThreadFactory會在創(chuàng)建線程時將線程設(shè)為守護線程,線程名例如:Thread [Tomcat(此處是容器的name)-startStop-1,5,main]。之后setStateInternal更新engine的LifecycleState狀態(tài)為INITIALIZED發(fā)布after_init事件。如果service之前add過Executor,會將這些Executor初始化,如果Executor是JmxEnabled則設(shè)置作用范圍。mapperListener的初始化沒有特殊邏輯,就是先改狀態(tài)為正在初始化并發(fā)布初始化之前的事件,然后注冊MBeanServer,再改狀態(tài)為初始化完成并發(fā)布初始化后事件。然后是在同步代碼塊中初始化Connector,不過之前已經(jīng)將Connector與Service解綁了,所以這里什么都沒做。于是,Service的初始化完成了,更新service的LifecycleState狀態(tài)為INITIALIZED發(fā)布after_init事件。接著Server的初始化也完成了,同樣也是更新狀態(tài)發(fā)布事件?;氐絊erver的start(雖然代碼在Lifecycle中),setStateInternal(LifecycleState.STARTING_PREP, null, false)更新LifecycleState狀態(tài)為準備啟動,發(fā)布before_start事件;startInternal首先發(fā)布一個configure_start事件,接著setState(LifecycleState.STARTING)就將狀態(tài)改為了STARTING同時發(fā)布start事件;globalNamingResources.start()更新狀態(tài)setStateInternal(LifecycleState.STARTING_PREP, null, false)發(fā)布before_start事件;globalNamingResources的startInternal方法,發(fā)布configure_start事件并setState(LifecycleState.STARTING),globalNamingResources啟動完成改狀態(tài)STARTED發(fā)布after_start事件;然后回到server代碼中,在同步代碼塊中啟動service:

 // Start our defined Services
  synchronized (servicesLock) {
   for (int i = 0; i < services.length; i++) {
    services[i].start();
   }
  }

當前狀態(tài)的Service會執(zhí)行setStateInternal(LifecycleState.STARTING_PREP, null, false),然后到StandardService的startInternal方法,setState(LifecycleState.STARTING)不說了,接著是同步代碼塊中engine.start(),里面是engine狀態(tài)變更setStateInternal(LifecycleState.STARTING_PREP, null, false),startInternal中super.startInternal執(zhí)行ContainerBase的對應(yīng)方法,初始化logger;然后((Lifecycle) realm).start(),start方法里又是一個循環(huán),從NEW到INITIALIZING的狀態(tài)變化,然后進入RealmBase的initInternal方法

 super.initInternal中MBeanServer,然后this.containerLog = container.getLogger(),此處container是StandardEngine[Tomcat],x509UsernameRetriever = createUsernameRetriever(x509UsernameRetrieverClassName),參考:https://bz.apache.org/bugzilla/show_bug.cgi&#63;id=52500;狀態(tài)連續(xù)更新到INITIALIZED然后STARTING_PREP,發(fā)布的什么事件我就不寫了,現(xiàn)在還在Realm[Simple]中,接著是RealmBase的startInternal方法,它初始化了credentialHandler = new MessageDigestCredentialHandler()并將狀態(tài)由改為了STARTING發(fā)布start事件,接著又改狀態(tài)了STARTED事件after_start;然后回到了StandardEngine [Tomcat]中,通過ContainerBase的findChildren方法找到了子容器:

隨后將host的啟動,提交給了之前初始化的startStopExecutor:

 for (int i = 0; i < children.length; i++) {
   results.add(startStopExecutor.submit(new StartChild(children[i])));
  }

借助Future<Void>獲取線程執(zhí)行的返回值;

下面就到了執(zhí)行注冊到engine的pipeline中的Value對象了((Lifecycle) pipeline).start(),StandardPipeline整套的狀態(tài)變化事件發(fā)布我就不寫了,initInternal方法是空實現(xiàn),需要說的只有pipeline的startInternal方法,會取第一個Value對象,如果沒有會執(zhí)行basic(StandardEngineValve[Tomcat]實例),最后會將pipeline中的Value對象依次start:    

 Valve current = first;
  if (current == null) {
   current = basic;
  }
  while (current != null) {
   if (current instanceof Lifecycle)
    ((Lifecycle) current).start();
   current = current.getNext();
  }

StandardEngineValve的整套start不說了,其中initInternal只有super.initInternal的MBeanServer和初始化containerLog,startInternal就只有改變狀態(tài)也不說了,出來后是pipeline的狀態(tài)變化,這個方法狀態(tài)都是變?yōu)镾TARTING標配也沒啥好說的,STARTED然后回到engine,StandardEngine[Tomcat]變狀態(tài)為STARTING,之后是threadStart(),代碼在ContainerBase中,啟動了背景線程:

上面configureEngine中配置的engine.setBackgroundProcessorDelay(this.backgroundProcessorDelay)指定背景線程的執(zhí)行間隔Thread.sleep((long) ContainerBase.this. backgroundProcessorDelay * 1000L),背景線程會處理例如StandardContext中e.getLoginConfig() == null時e.getPipeline().addValve(new NonLoginAuthenticator()),這個value包含session管理的相關(guān)邏輯,例如背景線程會在每隔多長時間后判斷session是否失效之類。終于StandardEngine實例也到了STARTED狀態(tài),該回到StandardService中了,前面說了我這并木有executor,所以沒執(zhí)行:

 synchronized (executors) {
   for (Executor executor: executors) {
    executor.start();
   }
  }

   然后是start前面初始化過的mapperListener:     

 setState(LifecycleState.STARTING);
  Engine engine = service.getContainer();
  if (engine == null) {
   return;
  }
  findDefaultHost();
  addListeners(engine);
  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
    registerHost(host);
   }
  }

上面代碼中給出的engine就是StandardEngine[Tomcat],findDefaultHost名字說的很清楚,我這里找出了localhost并set給MapperListener的mapper( mapper. setDefaultHostName ),addListeners本身是個遞歸,會將this(MapperListener)add給各個child容器(比如

StandardContext、StandardWrapper[default]和StandardWrapper[dispatcherServlet]):
  container.addContainerListener(this);
  container.addLifecycleListener(this);
  for (Container child : container.findChildren()) {
   addListeners(child);
  }

雖然是遞歸,但是只有一棵樹,所以返回的是children中的根child也就是StandardEngine[Tomcat].StandardHost[localhost],registerHost(host)這里的host就是這個根child,registerHost主要是處理映射關(guān)系包括別名和通配符并記錄(mapper.addHost(host.getName(), aliases, host)),然后處理它的子容器registerContext,及子容器的子容器wrapper并將各級子容器路徑關(guān)聯(lián)起來:        

boolean jspWildCard = (wrapperName.equals("jsp") && mapping.endsWith("/*"));
   wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard, resourceOnly));

關(guān)于在Springboot項目中內(nèi)嵌Tomcat時如何使用start就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

網(wǎng)站標題:在Springboot項目中內(nèi)嵌Tomcat時如何使用start
網(wǎng)站URL:http://aaarwkj.com/article46/pegheg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號搜索引擎優(yōu)化、網(wǎng)站排名、動態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司
国产精品久久99精品| 婷婷色爱区综合五月激情| 韩国av一区二区三区| 日韩国产一区二区在线观看| 亚洲日本日本午夜精品| 黑人巨大欧美一区二区| 小黄片视频免费在线播放| 深夜三级福利在线观看| 粉嫩一区二区三区av| 亚洲综合福利视频网站| 日本福利资源在线观看| 欧美性大片一区二区三区| 国产精品传媒在线观看网站| 男女生做刺激性视频网站| 国产精品伊人久久精品| 日本大胆高清人体艺术| 在线视频网友自拍偷拍| 日韩av一区二区人妻| 欧美色精品人妻视频在线| 国产看片色网站亚洲av| 中文字幕一区侵犯人妻| 国产成人福利视频在线观看| 久娜娜精品视频在线观看| 午夜影院在线观看网站| 亚洲性感美女男人的天堂| 18以下的人禁止看的视频| 国产色综合一区二区| 国产精品一区在线播放| 免费黄片视频大全在线播放| 国产成人精品手机在线观看| 欧美一级午夜欧美午夜视频| 99久久免费看国产精品| 亚洲一区二区三区视频在线观看| 亚洲一区二区视频精品| 乱码日本欧美一区二区| 国产精品国产三级区| 亚洲综合实力最强的国家| 国产高清不卡午夜福利| 午夜av一区二区三区| 国产三级精品在线免费| 欧美伊香蕉久久综合网99|