JBoss 的部署架構(gòu)可以分為三個部分:熱部署機制、部署的通用流程、部署的過程。
熱部署機制,使得我們在不需要重啟JBoss的情況下,可以增加、修改和刪除部署單元。JBoss會在運行時“察覺”到這些變化,并做出相應(yīng)的處理。
部署的通用流程,是一個對不同類型的部署單元都適用的部署過程。JBoss支持多種部署單元,包括jar格式的EJB組件、war格式的Web組件、ear格式的企業(yè)應(yīng)用組件、sar格式的服務(wù)組件、har格式的hibernate應(yīng)用等等。不同類型組件的部署過程是不同,但從宏觀的角度看,它們還有一個通用的流程。
部署的過程,就是每種類型組件自己獨特的部署操作。每種類型的組件都由一個特定的子部署器來完成部署過程。子部署器都是org.jboss.deployment.SubDeployer的子類。
部署單元可以是一個壓縮包,也可能一個目錄。JBoss使用DeploymentInfo對象來封裝部署單元的相關(guān)信息,在部署的過程,對DeploymentInfo對象進行操作。
在這篇文章中,我將介紹熱部署機制和部署的通用流程。由于可部署組件的類型太多,我就不一一介紹每種組件部署的過程。
首先,我先介紹部署的通用流程。
每種組件的部署都有三個階段,依次是init、create和start。這三個階段構(gòu)成了部署的通用流程。整個流程由org.jboss.deployment.MainDeployer負責(zé)管理。MainDeployer作為一個MBean,在JBoss啟動時被創(chuàng)建。部署一個組件,從調(diào)用MainDeploy的deploy方法開始。Deploy首先會調(diào)用MainDeploy的init方法,進入init階段。如果這一階段執(zhí)行成功,則接著調(diào)用MainDeploy的create方法,進入create階段。如果這一階段也執(zhí)行成功,則調(diào)用MainDeploy的start方法,進入start階段。如果這一階段也執(zhí)行成功,那么整個部署就成功了。現(xiàn)在讓我們看看MainDeploy在每個階段都做了什么事情。
Init階段:
首先,MainDeployer需要判斷部署單元是否要被解壓縮和拷貝到臨時目錄。一般來說,部署單元是被方法${JBOSS_HOME}/server/default/deploy目錄下。如果部署單元是一個目錄,那么就直接部署。如果部署單元是一個壓縮包,就需要將它解壓到${JBOSS_HOME}/server/default/tmp/deploy。解壓縮是可以理解的,為什么需要拷貝到臨時目錄呢?如果直接解壓縮到deploy目錄,那么JBoss就會將解壓后的目錄視為一個新的部署單元。這樣,一個部署單元被部署兩次,這是不可以的。
然后,MainDeployer將為部署單元查找能夠部署它的SubDeployer。例如,MainDeployer會為EJB組件找到EJBDeployer。所有的SubDeployer同MainDeployer一樣,都是在JBoss啟動時創(chuàng)建的。而且,每個SubDeployer都被注冊到MainDeployer中,這樣MainDeloyer就能找到它們。那么,MainDeployer是如何查找的呢?每種SubDeployer都會實現(xiàn)一個accepts方法,這個方法接收DeploymentInfo對象作為參數(shù),并判斷自己能不能部署它。如果能,返回true,否則返回false。MainDeployer就依次調(diào)用每個SubDeployer的accepts方法,MainDeplpyer將第一個返回true的SubDeployer,作為部署單元的SubDeployer。
接著,MainDeployer將部署單元添加到部署等待隊列中。這個隊列的作用是,如果某個部署單元因為依賴關(guān)系不滿足,而不能被部署,則將它暫存起來。但依賴關(guān)系滿足時,MainDeployer就可以從等待隊列中將它取出,并重新部署。
再接著,MainDeployer將調(diào)用部署單元的SubDeployer的init方法,進行特定于組件類型的初始化工作。
接著,MainDeployer為部署單元創(chuàng)建一個統(tǒng)一類加載器UCL,這個與JBoss的類加載器架構(gòu)有關(guān)。
再接著,MainDeployer讀取MANIFEST.MF文件,如果有引用的jar,將它們作為子部署單元,添加到部署單元中。
最后,調(diào)用MainDeployer.init方法(這是一個遞歸的過程),初始化所有的子部署單元。
Create階段:
首先,調(diào)用MainDeployer.create方法,創(chuàng)建所有的子部署單元。然后,調(diào)用部署單元的SubDepoyer的create方法(這是一個遞歸的過程),進行特定于組件類型的創(chuàng)建工作。
Start階段:
首先,調(diào)用MainDeployer.start方法,啟動所有的子部署單元。然后,調(diào)用部署單元的SubDeployer的start方法(這是一個遞歸的過程),進行特定于組件類型的啟動工作。最后,檢查部署單元關(guān)聯(lián)的所有MBean是不是都已經(jīng)啟動。如果沒有的話,整個部署就失敗了。
下面,我再介紹一下熱部署機制。熱部署機制的實現(xiàn)是很比較復(fù)雜的,有很多技術(shù)問題需要解決。但是它的結(jié)構(gòu)是很簡單的。所有需要熱部署的部署單元都方法deploy目錄下,有一個專門監(jiān)視該目錄的線程,它定期掃描目錄下的部署單元。如果有新的部署單元被添加進來,或者某個部署單元被刪除掉,該線程就會通知MainDeloyer部署或銷毀該部署單元。如果某個部署單元被修改,該線程就會通知MainDeployer充新部署該部署單元。該線程是通過文件的修改時間,來判斷某個部署單元是否被修改。org.jboss.deployment.scanner.URLDeploymentScanner負責(zé)熱部署的執(zhí)行。它作為一個MBean,在JBoss啟動時被創(chuàng)建。JBoss啟動時,會調(diào)用它的createService方法。該方法又會其父類AbstractDeploymentScanner的createService方法。其父親的createService方法會創(chuàng)建一個ScannerThread線程,這個線程每隔一段時間就會調(diào)用URLDeploymentScanner的scan方法。scan方法的工作就是檢查deploy目錄下的變化,并調(diào)用MainDeployer的相應(yīng)方法來進行重新部署、銷毀等操作。
熱部署機制,使得我們在不需要重啟JBoss的情況下,
部署的通用流程,是一個對不同類型的部署單元都適用的部
部署的過程,就是每種類型組件自己獨特的部署操作。每種
部署單元可以是一個壓縮包,也可能一個目錄。JBoss
在這篇文章中,我將介紹熱部署機制和部署的通用流程。由
首先,我先介紹部署的通用流程。
每種組件的部署都有三個階段,依次是init、crea
Init階段:
首先,MainDeployer需要判斷部署單元是否要
然后,MainDeployer將為部署單元查找能夠部
接著,MainDeployer將部署單元添加到部署等
再接著,MainDeployer將調(diào)用部署單元的Su
接著,MainDeployer為部署單元創(chuàng)建一個統(tǒng)一
再接著,MainDeployer讀取MANIFEST
最后,調(diào)用MainDeployer.init方法(這
Create階段:
首先,調(diào)用MainDeployer.create方法
Start階段:
首先,調(diào)用MainDeployer.start方法,
下面,我再介紹一下熱部署機制。熱部署機制的實現(xiàn)是很比