您當前位置>首頁 » 新聞資(zī)訊 » 網站(zhàn)建設 >
OSGi技術(shù)在Java Web開發中(zhōng)的應用
發表時間:2016-8-23
發布人:葵宇科技
浏覽次數:40
随着Java SE對模塊化功能原生支持的一再推遲(據最新的消息,Jigsaw項目——Java SE中(zhōng)的标準模塊系統——的開發工作相對滞後,已經延期到了Java 9中(zhōng),Java 9到2015年才有希望發布),OSGi作為事實标準的Java模塊化實現得到了長足的發展,尤其是随着雲計算和(hé)分布式技術(shù)的興起,OSGi這種模塊化、動(dòng)态部署的核心功能将會受到越來越多的重視。
目前OSGi規範的主流實現框架是Eclipse Equinox以及Apache Felix,其實際的應用場景也早就從起初的嵌入式設備擴展到桌面應用甚至Java企業(yè)級開發領域。最為大家所熟知的OSGi應用是Eclipse IDE,其實像Sun GlassFish、IBM WebSphere Application Server、JBoss Application Server以及Apache的大量開源項目如(rú)Camel、Sling、ServiceMix、Kafaf等都使用了OSGi技術(shù),随着其應用的日益廣泛,技術(shù)的可(kě)用性和(hé)成熟度經受了充分的考驗,實踐證明OSGi是一項可(kě)靠的技術(shù),完全可(kě)以應用于企業(yè)級應用的開發。尤其值得一提的是,随着OSGi Core Release 5和(hé)OSGi Enterprise Release 5版本的發布,預計OSGi技術(shù)将會受到更多的關(guān)注,國内外已經有将OSGi應用于雲計算和(hé)分布式計算的案例。
本文(wén)将選取OSGi應用于傳統Java Web開發的場景,介紹借助于OSGi技術(shù),怎樣實現将Web應用拆分成滿足OSGi規範的bundle,實現組件的動(dòng)态部署。目前,為了實現在bundle中(zhōng)支持JSP、Servlet等Java Web開發技術(shù)和(hé)規範,有兩種主要的開發部署方式,本文(wén)都将進行介紹,但是這兩種方案在實現上與傳統的Java Web應用開發模式有較大的不同,且對JEE規範的支持尚不完整。
按照Eclipse Equinox的習慣,會将bundle稱為插件,在後文(wén)中(zhōng)會根據具體的應用場景穿插使用這兩個(gè)名詞,但其本質是相同的。
1.1 将Web容器(qì)作為bundle置于Equinox中(zhōng)進行開發
在這種模式下(xià),我們需要将支持JEE規範的容器(qì)也以bundle形式發布到OSGi容器(qì)中(zhōng),而包含JSP、Servlet的bundle将會使用該容器(qì)接受對請求的訪問(wèn),這種方式的好處在于OSGi容器(qì)管理整個(gè)運行環境,是個(gè)純粹的可(kě)熱插拔運行環境,其缺點在于需要Web容器(qì)支持以bundle的形式進行發布,對運行環境有一定的限制,目前支持該要求的Web容器(qì)有Tomcat和(hé)Jetty,但是主流的企業(yè)級應用服務器(qì)尚不支持這種部署方式。
鑒于Eclipse開發環境中(zhōng)已經包含了Jetty服務器(qì),所以我們将會使用該服務器(qì)進行Web應用的開發。
首先我們需要使用Eclipse的工程向導創建一個(gè)插件工程。根據工程的需要,我們不生成啟動(dòng)類(activator),不使用任何模版,創建過程如(rú)下(xià):
新建一個(gè)插件工程:
輸入工程的基本信息:
此處我們不使用任何模版,因為我們不會用到Eclipse的UI功能:
新建完成的項目結構如(rú)下(xià)所示:
為了測試進行Web開發,我們新建目錄結構/WebRoot/jsp(該目錄名稱是任意的,隻需在後續定義擴展點時進行匹配即可(kě))并在該目錄下(xià)創建一個(gè)JSP文(wén)件,此時的工程結構如(rú)下(xià):
JSP的代碼如(rú)下(xià):
<%@pagelanguage="java"contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> Hello,world! </body> </html>
為了使用JSP和(hé)Servlet,我們需要使用一個(gè)擴展點,該擴展的名稱為org.eclipse.equinox.http.registry.servlets,我們需要使用該擴展點進行JSP目錄和(hé)訪問(wèn)地址的匹配,在這個(gè)樣例中(zhōng)我們匹配了/WebRoot/jsp目錄,其訪問(wèn)地址的前綴将會是/jsp/:
除此以外,我們還需要添加對org.eclipse.equinox.jsp.jasper.registry插件的依賴,以實現JSP的編譯功能。
最後,我們在運行時配置裡将testweb和(hé)Jetty所依賴的插件全部選中(zhōng),如(rú)下(xià):
點擊“Run”按鈕,此時就會啟動(dòng)OSGi運行環境,我們可(kě)以在控制台通(tōng)過使用“ss”命令來查看運行插件的狀态情況:
此時,可(kě)以在浏覽器(qì)中(zhōng)輸入http://localhost/jsp/index.jsp(Jetty的默認端口是80,可(kě)進行配置),就會看到我們所編寫的JSP的代碼了:
要實現訪問(wèn)Servlet和(hé)靜态資(zī)源(CSS、圖片等),也需要類似的配置,下(xià)圖是一個(gè)包含靜态資(zī)源和(hé)Servlet的配置樣例所對應的plugin.xml文(wén)件内容:
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension point="org.eclipse.equinox.http.registry.servlets"> <servlet alias="/servlet/myfirstservlet" class="testjsp.LoginServlet" load-on-startup="true"> </servlet> <servlet alias="/jsp/404.html" class="org.eclipse.equinox.jsp.jasper.registry.JSPFactory:/WebRoot/jsp/"> </servlet> </extension> <extension point="org.eclipse.equinox.http.registry.resources"> <resource alias="/web" base-name="/WebRoot/images"/> </extension> </plugin>
以上就實現了訪問(wèn)JSP和(hé)Servlet等Java Web技術(shù)的功能,如(rú)果要将其用在實際的運行環境中(zhōng),可(kě)以将這個(gè)插件打成jar包的形式,将該jar包和(hé)其依賴的插件放在Equinox指定目錄下(xià),通(tōng)過命令行來啟動(dòng)bundle并進行訪問(wèn)。
1.2 将Equinox置于web容器(qì)中(zhōng)進行開發
以上的開發模式對于習慣于傳統JEE開發模式的開發人員在接受上有一定的難度,直接使用Equinox作為運行環境在解決集群部署方面也有一定的難度,除此以外,主流的應用服務器(qì)并不提供bundle形式的jar以運行在OSGi容器(qì)中(zhōng)。所以,開發人員摸索出了另一種開發和(hé)部署模式。
在這種模式中(zhōng),會将Equinox和(hé)我們開發的插件都打成一個(gè)标準的war包的格式,因此可(kě)以運行在任意支持JEE的容器(qì)中(zhōng)。Equinox的生命周期是通(tōng)過Servlet來進行控制。這種模式被稱為橋接模式。Equinox官方提供了該模式的實現,後來的社區貢獻者基于此進行了功能的完善。
将下(xià)載後的代碼導入到Eclipse中(zhōng),工程目錄如(rú)下(xià)所示:
從該目錄可(kě)以看出,這是一個(gè)典型JEE工程,可(kě)以運行在任意的支持規範的Web容器(qì)或應用服務器(qì)中(zhōng),查看web.xml,我們可(kě)以看到這樣的配置:
<servlet id="bridge"> <servlet-name>equinoxbridgeservlet</servlet-name> <display-name>Equinox Bridge Servlet</display-name> <description>Equinox Bridge Servlet</description> <servlet-class>org.eclipse.equinox.servletbridge.BridgeServlet</servlet-class> <init-param> <param-name>commandline</param-name> <param-value>-console</param-value> </init-param> <init-param> <param-name>enableFrameworkControls</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>extendedFrameworkExports</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>equinoxbridgeservlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>equinoxbridgeservlet</servlet-name> <url-pattern>404.html</url-pattern> </servlet-mapping>
我們可(kě)以看到這個(gè)Servlet攔截了所有的請求,由該Servlet代理所有的請求。
在部署階段,可(kě)以把插件打成jar包,放到/WEB-INF/eclipse/plugins目錄下(xià)即可(kě)。如(rú)将我們上例中(zhōng)的testweb導出為jar包後,置于指定目錄下(xià)。然後在Tomcat中(zhōng)運行該應用。訪問(wèn)http://localhost:8080/bridge/jsp/index.jsp就可(kě)以看到我們編寫的JSP頁面了。
使用以上的模式進行開發,對原有的開發和(hé)部署模式沖擊較小而且支持所有的應用服務器(qì)。
參考資(zī)料:
http://www.ibm.com/developerworks/cn/web/0907_osgiweb_liuqing/