21.Spring Bean及Java類的熱部署
簡介
在URule Pro中(zhōng)支持Spring Bean及Java類的熱部署功能(néng),利用(yòng)該功能(néng),可(kě)将需要熱部署的Spring Bean及相關Java類文(wén)件實時部署到正在運行的服務(wù)器中(zhōng)。 對于采用(yòng)客戶端服務(wù)器模式運行的URule Pro應用(yòng),隻需要在服務(wù)端部署好需要的Spring Bean及相關Java類文(wén)件,客戶端會自動獲取這些已部署的Spring Bean及相關Java類文(wén)件信息,并對其進行執加載。
有(yǒu)了這個功能(néng),URule Pro中(zhōng)無論是用(yòng)戶自定義的動作(zuò)庫還是内置動作(zuò)庫相關的Spring Bean及Java類,都可(kě)以在服務(wù)器運行情況下,實時動态部署。
部署方式
登錄系統,在進入团隊主頁(yè)面即可(kě)看到Jar文(wén)件熱部署入口鏈接,如下图:
打開Jar文(wén)件熱部署的管理(lǐ)頁(yè)面,點擊工(gōng)具(jù)欄上“添加Jar文(wén)件”按鈕添加一個新(xīn)的部署項,在彈出的窗口中(zhōng)輸入項目名(míng)稱,點擊“确定”後就會出現文(wén)件上傳按鈕,選擇一個合适的jar文(wén)件上傳即可(kě)。如下图所示:
完成之後點擊頁(yè)面工(gōng)具(jù)欄上“部署”,即可(kě)将所有(yǒu)部署項中(zhōng)上傳的Jar文(wén)件動态部署到當前項目中(zhōng);如果當前項目被當成URule Server使用(yòng),同時又(yòu)在項目裏配置了客戶端地址,那麽在Server上部署完成後,系統會提示我們要不要将這些動态的Jar文(wén)件推送到URule客戶端,如果選擇是,那麽這些客戶端立即接收到這些Jar文(wén)件并動态加載。
Spring配置文(wén)件及Jar文(wén)件要求
從部署方式上了解到,我們隻需要将需要熱部署的Jar包上傳到系統即可(kě),如果其中(zhōng)要加載Spring Bean,那麽還需要定義好Spring的xml配置文(wén)件放在Jar包中(zhōng)一并上傳,下面來舉例說明Spring配置文(wén)件及Jar文(wén)件打包方式。
假如我們需要部署下面這個Java類文(wén)件,内容如下:
package test;
/**
* @author Jacky.gao
* @since 2019年1月11日
*/
public class BusinessTest {
public String hello(String name) {
System.out.println(new OtherBusiness().getENV());
return "Hello, "+name;
}
}
從上面的代碼中(zhōng)可(kě)以看出,這裏的hello方法引用(yòng)了OtherBusiness類中(zhōng)的getENV方法,OtherBusiness類源碼如下:
package test;
/**
* @author Jacky.gao
* @since 2019年1月11日
*/
public class OtherBusiness {
public String getENV() {
return "環境 is OK...";
}
}
可(kě)以看到getENV方法非常簡單,隻是返回一個字符串而已,對于BusinessTest類,我們希望它成為(wèi)一個标準的Spring Bean,所以還要添加一個Spring的xml配置文(wén)件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<bean id="dybean" class="test.BusinessTest"></bean>
</beans>
在上面這段xml配置中(zhōng),test.BusinessTest類被配置成為(wèi)一個标準的Spring Bean,Bean的ID為(wèi)dybean。到這裏Java類的編寫及Spring Bean的xml配置工(gōng)作(zuò)就完成了,接下來就需要将它們打包Jar并上傳到URule中(zhōng)實際熱部署。
為(wèi)了演示Java類引用(yòng)多(duō)個不同Jar包中(zhōng)其它類庫的情形,這裏我們把BusinessTest類和OtherBusiness類打成兩個Jar文(wén)件,分(fēn)别是main.jar和slave.jar,至于Spring Bean的xml配置文(wén)件放在兩個Jar文(wén)件中(zhōng)任何一個中(zhōng)都可(kě)以,隻是xml的名(míng)稱必須是urule-spring-context.xml,且這個名(míng)為(wèi)urule-spring-context.xml的Spring配置文(wén)件必須放在Jar文(wén)件的根下,這裏我們把這個urule-spring-context.xml文(wén)件打包在main.jar文(wén)件當中(zhōng)。
打包好的main.jar文(wén)件結構如下图所示:
打包好的slave.jar文(wén)件結構如下图所示:
上面的兩個Jar文(wén)件中(zhōng),BusinessTest類和OtherBusiness類都位于test這個package下,所以截图中(zhōng)隻看到test這個package。 對于URule Pro來說,每個Jar文(wén)件中(zhōng)都可(kě)以包含一個名(míng)為(wèi)urule-spring-context.xml的Spring的xml配置文(wén)件,如果包含每個文(wén)件中(zhōng)的Spring配置文(wén)件都會被解析并加載; 當然也可(kě)以都不包含,這樣熱部署時引擎隻會加載Jar包中(zhōng)的類。
配置
當我們點擊“态部署Jar文(wén)件的配置頁(yè)面”上的部署按鈕時,系統會嘗試取到知識庫裏所有(yǒu)已上傳的Jar文(wén)件,然後通過System.getProperty("java.io.tmpdir")取到當前JVM應用(yòng)的臨時目錄,同時在其下創建名(míng)為(wèi)urule-jars的目錄,最後取當前系統日期作(zuò)為(wèi)Jar文(wén)件的最終存儲目錄。
每次點擊“部署”按鈕時,系統都會嘗試删除原來的由系統日期生成的子目錄,再根據當前日期重新(xīn)創建子目錄,再把所有(yǒu)的Jar文(wén)件放在這個目錄下。
在臨時目錄中(zhōng)生成好所有(yǒu)的已上傳的Jar文(wén)件後,接下來系統會嘗試加載這個目錄下的所有(yǒu)Jar文(wén)件,如果這些Jar文(wén)件根下包含名(míng)為(wèi) urule-spring-context.xml的Spring配置文(wén)件,系統也會将這個文(wén)件加載到Spring上下文(wén)中(zhōng)。
實際使用(yòng)中(zhōng),如果不想讓引擎通過System.getProperty("java.io.tmpdir")這種方式,取到的臨時目錄來作(zuò)為(wèi)動态Jar文(wén)件的存儲父目錄,那麽可(kě)以在Spring的Properties文(wén)件中(zhōng)添加一個名(míng)為(wèi)urule.dynamicJarsPath的屬性來手工(gōng)指定一個用(yòng)于存儲動态Jar文(wén)件的 父目錄,需要注意的是通過urule.dynamicJarsPath屬性指定的目錄一定要存在,否則啓動時會産(chǎn)生錯誤。
對于采用(yòng)客戶端服務(wù)器模式運行的應用(yòng)來說,如果客戶端是一個Java Web應用(yòng),那麽隻需要按照客戶端服務(wù)器模式中(zhōng)介紹的在客戶端中(zhōng)配置好接收服務(wù)端推送過來的知識庫的Servlet即可(kě),這樣服務(wù)端動态Jar部署時會提示是否推送到客戶端,如果選是,那麽這些動态Jar文(wén)件會直接推送到目标客戶端,客戶端收到後也會按照上述方式加載這些Jar文(wén)件及其中(zhōng)可(kě)能(néng)存在的名(míng)為(wèi)urule-spring-context.xml的Spring配置文(wén)件。
和知識包的客戶端一樣,客戶端也可(kě)以主動檢查服務(wù)端是否存在動态Jar文(wén)件,檢查方式也是在客戶端上配置“urule.resporityServerUrl”屬性值,客戶端中(zhōng)配置好“urule.resporityServerUrl”屬性值後,客戶端應用(yòng)除了會利用(yòng)這個URL到服務(wù)端下載規則包,還會在啓動時利用(yòng)這個URL檢查服務(wù)端是否存在動态加載的Jar文(wén)件,如果有(yǒu)則下載到客戶端并加載;這時服務(wù)端的“urule/dynamic/checkLatestJarsDir”和“urule/dynamic/loadDynamicJars”這兩個URL要保證匿名(míng)可(kě)訪問,否則客戶端啓動時會産(chǎn)生錯誤。
如果客戶端是一個标準的Java應用(yòng),而非一個Java Web應用(yòng),對于這種類型的應用(yòng)來說,為(wèi)了可(kě)以取到服務(wù)端生成的動态Jar文(wén)件,我們可(kě)以在客戶端Spring的Properties文(wén)件中(zhōng)添加一個名(míng)為(wèi)urule.dynamicJarsRemoteLoadInterval的屬性 來決定客戶端每隔多(duō)久利用(yòng)客戶端上配置的urule.resporityServerUrl屬性值到服務(wù)端檢查有(yǒu)沒有(yǒu)新(xīn)的動态Jar産(chǎn)生,如果有(yǒu)則從服務(wù)端取回并加載。
urule.dynamicJarsRemoteLoadInterval的屬性值單位為(wèi)分(fēn)鍾,如果我們設置其值為(wèi)5,那就表示每隔5分(fēn)鍾到服務(wù)端檢查是否生成新(xīn)的動态Jar文(wén)件,如果不設置則表示客戶端不會定期檢查服務(wù)端是否有(yǒu)新(xīn)的動态Jar包産(chǎn)生。
如果是springboot項目,需要在spring的配置文(wén)件中(zhōng)添加屬性配置
spring.main.allow-bean-definition-overriding=true