【OSGI】4.实战OSGI-翻译助手项目02
生活随笔
收集整理的這篇文章主要介紹了
【OSGI】4.实战OSGI-翻译助手项目02
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上次我們配置了運行Web項目所需要的Run Configuration環境,創建了客戶端入口插件TranslateClient模塊,下面我們來繼續完成客戶端模塊的程序。
因為是Web項目,我們要讓用戶通過瀏覽器去訪問我們的應用,所以我們要去寫一些Servlet來處理Http請求。
因為我們的工程是plug-in工程,不是傳統的Web project,所以不能直接創建一個Servlet(因為涉及到Web.xm的mapping映射和訪問路徑的設置),我們需要創建一個類,讓它去繼承HttpServlet來實現這個Servlet。
首先我們先在MANIFEST.MF文件中通過配置導入Servlet的相關包:
然后寫一個類繼承HttpServlet來實現這個Servlet:
package com.zyg.osgi.translateclient.servlet;import java.io.IOException;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.osgi.framework.BundleContext;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;public TranslateServiceServlet(BundleContext bundleContext) {// TODO Auto-generated constructor stub}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {} }我們先不寫其中的邏輯,我們先寫一個最后跳轉到的靜態頁面(html)。
一提到寫靜態頁面,那么問題來了,我們平時寫Web項目的時候,我們的靜態頁面都是寫在WebContext或者WebRoot文件夾下的:
那么我們這個項目并沒有這些目錄,那我們怎么去訪問我們的靜態頁面呢?用什么路徑去訪問呢?是不是感覺和我們之前的開發過程幾乎完全不一樣,有點不太習慣,不知道從哪里下手?
告訴大家,不!要!慌!雖然使用osgi進行Web開發和之前有很大不同,但是我們無非是把IDE工具中的Web project給我們自動做好的事情,我們手動去完成它而已~~~~
osgi的plug-in和普通web project的不同之處不外乎就是文件的組織夾結構上不太一樣。但是如果我們自己手動在工程中創建一個WebContext文件夾,然后里面創建META-INF、WEB-INF和一些jsp文件,形成和web project的靜態文件夾組織結構,我們再把這些文件和文件夾的路徑給需要加載這個靜態文件的程序(例如TomCat,當然我們這里不是TomCat),不就和之前的web project中的靜態文件被自動加載的原理一模一樣了嗎?所以我們可以這么做,只是需要我們多動一下手去實現它。(說白了,文件夾的擺放只是一個形式,重點在處理路徑的程序。我們掌握了處理路徑的程序之后,怎么使用我們不一定非要聽從第三方的規定,我們按照我們自己喜歡的方式來搞,豈不是更牛逼)
為了方便讀取,我們把我們的靜態文件直接放在類路徑下:
其中html文件的內容是:
<HTML> <HEAD> <TITLE>OSGi Dictionary Query Demo</TITLE> <meta http-equiv="Content-Type" content="text/html;charset=GBK" /> <script>function queryWord(){if(document.frmCalc.query_word.value==""){alert("必須輸入單詞");document.frmCalc.query_word.focus();return;}document.frmCalc.submit();} </script> </HEAD><BODY> <table style="width:100px;border:1px solid;height:100px"><form name="frmCalc" method="post" action="/servlet/translateServlet"><tr bgcolor="#C0C0C0"><td colspan="4" align="center">翻譯助手</td></tr><tr><td><input type="text" name="query_word" size="20"></td><td><input type=button name=btnSubmit value="查詢" οnclick="queryWord();"></td></tr></form> </table> </BODY> </HTML>
好的,我們將我們需要搜索的單詞提交上去,那么我們的后臺怎么接收呢?
我們之前寫Servlet的時候還需要在Web-INF的Web.xml中去注冊mapping映射,就像這樣:
<servlet><servlet-name>Add</servlet-name><servlet-class>cn.edu.hpu.test.add</servlet-class> </servlet><servlet-mapping><servlet-name>Add</servlet-name><url-pattern>/add</url-pattern> </servlet-mapping>但是我們的plug-in項目是沒有這種配置文件的,所以我們要來解決這個問題。
首先我們來剖析一下原來的Servlet的mapping映射原理,因為如果我們了解原理之后,我們可以模擬Web-INF的Web.xml中注冊mapping映射的原理,去給我們自己的Servlet去注冊映射。
開始剖析:
我們之前新建的Servlet我們如果不在Web.xml中做映射配置的話,我們的TomCat服務器是不知道這個Servlet的存在的,也就是我們訪問不到這個Servlet的,因為TomCat是通過讀取Web.xml文件來實例化Servlet到內存中去的。
我們沒有Web.xml文件的話怎么辦呢?我們來轉換一下思維:我們的Web.xml是要通過程序來讀取,然后把里面配置的Servlet給讀取到內存中去實例化。歸根結底還是需要程序來進行實例化,那么我們為什么不自己去進行實例化呢?我們不要Web.xml配置文件,我們手動在容器中去執行。
那么我們該怎么寫這種程序呢?又是一個問題。
如果大家分析過TomCat的源碼的話,應該會對這個有一些小小的思路,但是我們這里不會像TomCat這樣做的那么嚴格,我們簡單的來實現TomCat讀取配置和注冊這兩個部分的代碼,我們要把Servlet注冊到容器的服務中去。
我們將這些代碼在控制bundle聲明周期的Activator類中。
我們首先讓Activator首先實現osgi的ServiceListener接口,并重寫它的serviceChanged方法,我們才能夠通過它來得到jetty服務器給我們提供的各種http服務:
package com.zyg.osgi.translateclient;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;}public void stop(BundleContext bundleContext) throws Exception {Activator.context = null;}@Overridepublic void serviceChanged(ServiceEvent arg0) {// TODO Auto-generated method stub}}
我們在其中編寫獲取HttpService,注冊和注銷Servlet以及靜態資源的方法:
package com.zyg.osgi.translateclient;import javax.servlet.Servlet; import javax.servlet.ServletException;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpService; import org.osgi.service.http.NamespaceException;import com.zyg.osgi.translateclient.servlet.TranslateServiceServlet;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;private ServiceReference serviceReference;private Servlet servlet;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//在TranslateServiceServlet中創建一個構造方法,將bundleContext傳進去servlet=new TranslateServiceServlet(bundleContext);//注冊ServletregisterServlet();}public void stop(BundleContext bundleContext) throws Exception {//注銷Servlet等資源unRegisterServlet();serviceReference=null;Activator.context = null;}private void registerServlet() {if(null==serviceReference){//通過上下文獲取服務對象的“引用”(需要通過MANIFEST.MF引入org.osgi.service.http包)serviceReference=context.getServiceReference(HttpService.class);}if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注冊Servlet//四個參數分別是:(映射地址,Servlet類本身,Dictionary,上下文)httpService.registerServlet("/servlet/translateServlet", servlet, null, null);//注冊靜態資源(html等文件)位置//四個參數分別是(訪問地址,靜態文件所在路徑,上下文)httpService.registerResources("/page", "pages", null);System.out.println("翻譯助手服務已啟動成功,請通過/page/translate.html訪問!");} catch (ServletException e) {e.printStackTrace();} catch (NamespaceException e) {e.printStackTrace();}}}}private void unRegisterServlet() {if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注銷Servlet//四個參數分別是:映射地址httpService.unregister("/servlet/translateServlet");//注銷靜態資源(html等文件)位置//參數是訪問地址httpService.unregister("/page");System.out.println("翻譯助手服務已停用成功,謝謝使用!");} catch (Exception e) {e.printStackTrace();}}}}@Overridepublic void serviceChanged(ServiceEvent event) {// TODO Auto-generated method stubswitch (event.getType()) {case ServiceEvent.REGISTERED:registerServlet();break;case ServiceEvent.UNREGISTERING:unRegisterServlet();break;default:break;}} }
然后編寫我們的Servlet:
package com.zyg.osgi.translateclient.servlet;import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference;import com.zyg.osgi.translateasslt.service.TranslateService;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;private BundleContext context;public TranslateServiceServlet(BundleContext bundleContext) {this.context=bundleContext;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {//1、取得用戶傳來的英文單詞String queryWord=req.getParameter("query_word");//2、調用方法查找中文含義//獲取服務TranslateService translateService=null;ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());if(null!=serviceRef){translateService=(TranslateService)context.getService(serviceRef);}//3、返回結果給用戶resp.setContentType("text/html;charset=GBK");PrintWriter writer=resp.getWriter();if(translateService==null){writer.println("沒有開放翻譯服務!");writer.close();return;}String result=translateService.translate(queryWord);writer.println("結果"+result);writer.close();return;}}其中需要通過MANIFEST.MF引入com.zyg.osgi.translateasslt.service包。
同時,我們要在localTranslateAsslt和remoteTranslateAsslt這兩個插件的Activator中注冊相應的Service,這樣我們的TranslateClient就可以使用它們兩個提供的Service服務了:
package com.zyg.osgi.localtranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.localtranslateasslt.impls.TranslateServiceLocalImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceLocalImpl(), null);System.out.println("本地查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("本地查詢服務已停止!");Activator.context = null;} }
package com.zyg.osgi.remotetranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.remotetranslateasslt.impls.TranslateServiceRemoteImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceRemoteImpl(), null);System.out.println("遠程查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("遠程查詢服務已停止!");Activator.context = null;} }
好的,目前我們的工作基本完成!現在啟動osgi來看看我們的戰果把:
說明我們運行成功了,我們來進入瀏覽器訪問一下我們的靜態頁面:
這說明我們的Web項目起來了,并且靜態資源也訪問成功了。
然后我們來查詢一下單詞,看看我們的Servlet和Service是不是也注冊和實例化成功了:
我們先查本地服務的單詞“USA”的意思
我們再來查詢遠程服務的單詞“cat”的意思
出現這種原因的結果是我們兩個服務都開啟了,但是因為先注冊了Local服務后注冊了Remote服務,二者服務名相同,所以Remote服務把Local服務給覆蓋掉了,那么我們訪問本地Local服務的時候,就訪問不到相應的數據,訪問Remote服務卻可以。
大家可以在看控制臺出入ss,可以看到遠程和本地兩個服務都存在:
我們現在stop掉遠程服務:
因為通過熱部署,我們網站不需要重啟,我們直接訪問遠程服務:
發現遠程已經不能訪問,那么我們訪問本地的服務:
本地服務正常。
當然反過來只用遠程的服務也可以。
所以這體現了一種插件“即插即用”,拔除不影響其他組件的性能。
停止服務,關閉osgi的啟動,我們需要在控制臺中輸入close即可:
以上就是我們利用osgi完成的一個服務可插拔的Web項目。
因為是Web項目,我們要讓用戶通過瀏覽器去訪問我們的應用,所以我們要去寫一些Servlet來處理Http請求。
因為我們的工程是plug-in工程,不是傳統的Web project,所以不能直接創建一個Servlet(因為涉及到Web.xm的mapping映射和訪問路徑的設置),我們需要創建一個類,讓它去繼承HttpServlet來實現這個Servlet。
首先我們先在MANIFEST.MF文件中通過配置導入Servlet的相關包:
然后寫一個類繼承HttpServlet來實現這個Servlet:
package com.zyg.osgi.translateclient.servlet;import java.io.IOException;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.osgi.framework.BundleContext;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;public TranslateServiceServlet(BundleContext bundleContext) {// TODO Auto-generated constructor stub}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {} }我們先不寫其中的邏輯,我們先寫一個最后跳轉到的靜態頁面(html)。
一提到寫靜態頁面,那么問題來了,我們平時寫Web項目的時候,我們的靜態頁面都是寫在WebContext或者WebRoot文件夾下的:
那么我們這個項目并沒有這些目錄,那我們怎么去訪問我們的靜態頁面呢?用什么路徑去訪問呢?是不是感覺和我們之前的開發過程幾乎完全不一樣,有點不太習慣,不知道從哪里下手?
告訴大家,不!要!慌!雖然使用osgi進行Web開發和之前有很大不同,但是我們無非是把IDE工具中的Web project給我們自動做好的事情,我們手動去完成它而已~~~~
osgi的plug-in和普通web project的不同之處不外乎就是文件的組織夾結構上不太一樣。但是如果我們自己手動在工程中創建一個WebContext文件夾,然后里面創建META-INF、WEB-INF和一些jsp文件,形成和web project的靜態文件夾組織結構,我們再把這些文件和文件夾的路徑給需要加載這個靜態文件的程序(例如TomCat,當然我們這里不是TomCat),不就和之前的web project中的靜態文件被自動加載的原理一模一樣了嗎?所以我們可以這么做,只是需要我們多動一下手去實現它。(說白了,文件夾的擺放只是一個形式,重點在處理路徑的程序。我們掌握了處理路徑的程序之后,怎么使用我們不一定非要聽從第三方的規定,我們按照我們自己喜歡的方式來搞,豈不是更牛逼)
為了方便讀取,我們把我們的靜態文件直接放在類路徑下:
其中html文件的內容是:
<HTML> <HEAD> <TITLE>OSGi Dictionary Query Demo</TITLE> <meta http-equiv="Content-Type" content="text/html;charset=GBK" /> <script>function queryWord(){if(document.frmCalc.query_word.value==""){alert("必須輸入單詞");document.frmCalc.query_word.focus();return;}document.frmCalc.submit();} </script> </HEAD><BODY> <table style="width:100px;border:1px solid;height:100px"><form name="frmCalc" method="post" action="/servlet/translateServlet"><tr bgcolor="#C0C0C0"><td colspan="4" align="center">翻譯助手</td></tr><tr><td><input type="text" name="query_word" size="20"></td><td><input type=button name=btnSubmit value="查詢" οnclick="queryWord();"></td></tr></form> </table> </BODY> </HTML>
好的,我們將我們需要搜索的單詞提交上去,那么我們的后臺怎么接收呢?
我們之前寫Servlet的時候還需要在Web-INF的Web.xml中去注冊mapping映射,就像這樣:
<servlet><servlet-name>Add</servlet-name><servlet-class>cn.edu.hpu.test.add</servlet-class> </servlet><servlet-mapping><servlet-name>Add</servlet-name><url-pattern>/add</url-pattern> </servlet-mapping>但是我們的plug-in項目是沒有這種配置文件的,所以我們要來解決這個問題。
首先我們來剖析一下原來的Servlet的mapping映射原理,因為如果我們了解原理之后,我們可以模擬Web-INF的Web.xml中注冊mapping映射的原理,去給我們自己的Servlet去注冊映射。
開始剖析:
我們之前新建的Servlet我們如果不在Web.xml中做映射配置的話,我們的TomCat服務器是不知道這個Servlet的存在的,也就是我們訪問不到這個Servlet的,因為TomCat是通過讀取Web.xml文件來實例化Servlet到內存中去的。
我們沒有Web.xml文件的話怎么辦呢?我們來轉換一下思維:我們的Web.xml是要通過程序來讀取,然后把里面配置的Servlet給讀取到內存中去實例化。歸根結底還是需要程序來進行實例化,那么我們為什么不自己去進行實例化呢?我們不要Web.xml配置文件,我們手動在容器中去執行。
那么我們該怎么寫這種程序呢?又是一個問題。
如果大家分析過TomCat的源碼的話,應該會對這個有一些小小的思路,但是我們這里不會像TomCat這樣做的那么嚴格,我們簡單的來實現TomCat讀取配置和注冊這兩個部分的代碼,我們要把Servlet注冊到容器的服務中去。
我們將這些代碼在控制bundle聲明周期的Activator類中。
我們首先讓Activator首先實現osgi的ServiceListener接口,并重寫它的serviceChanged方法,我們才能夠通過它來得到jetty服務器給我們提供的各種http服務:
package com.zyg.osgi.translateclient;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;}public void stop(BundleContext bundleContext) throws Exception {Activator.context = null;}@Overridepublic void serviceChanged(ServiceEvent arg0) {// TODO Auto-generated method stub}}
我們在其中編寫獲取HttpService,注冊和注銷Servlet以及靜態資源的方法:
package com.zyg.osgi.translateclient;import javax.servlet.Servlet; import javax.servlet.ServletException;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpService; import org.osgi.service.http.NamespaceException;import com.zyg.osgi.translateclient.servlet.TranslateServiceServlet;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;private ServiceReference serviceReference;private Servlet servlet;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//在TranslateServiceServlet中創建一個構造方法,將bundleContext傳進去servlet=new TranslateServiceServlet(bundleContext);//注冊ServletregisterServlet();}public void stop(BundleContext bundleContext) throws Exception {//注銷Servlet等資源unRegisterServlet();serviceReference=null;Activator.context = null;}private void registerServlet() {if(null==serviceReference){//通過上下文獲取服務對象的“引用”(需要通過MANIFEST.MF引入org.osgi.service.http包)serviceReference=context.getServiceReference(HttpService.class);}if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注冊Servlet//四個參數分別是:(映射地址,Servlet類本身,Dictionary,上下文)httpService.registerServlet("/servlet/translateServlet", servlet, null, null);//注冊靜態資源(html等文件)位置//四個參數分別是(訪問地址,靜態文件所在路徑,上下文)httpService.registerResources("/page", "pages", null);System.out.println("翻譯助手服務已啟動成功,請通過/page/translate.html訪問!");} catch (ServletException e) {e.printStackTrace();} catch (NamespaceException e) {e.printStackTrace();}}}}private void unRegisterServlet() {if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注銷Servlet//四個參數分別是:映射地址httpService.unregister("/servlet/translateServlet");//注銷靜態資源(html等文件)位置//參數是訪問地址httpService.unregister("/page");System.out.println("翻譯助手服務已停用成功,謝謝使用!");} catch (Exception e) {e.printStackTrace();}}}}@Overridepublic void serviceChanged(ServiceEvent event) {// TODO Auto-generated method stubswitch (event.getType()) {case ServiceEvent.REGISTERED:registerServlet();break;case ServiceEvent.UNREGISTERING:unRegisterServlet();break;default:break;}} }
然后編寫我們的Servlet:
package com.zyg.osgi.translateclient.servlet;import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference;import com.zyg.osgi.translateasslt.service.TranslateService;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;private BundleContext context;public TranslateServiceServlet(BundleContext bundleContext) {this.context=bundleContext;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {//1、取得用戶傳來的英文單詞String queryWord=req.getParameter("query_word");//2、調用方法查找中文含義//獲取服務TranslateService translateService=null;ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());if(null!=serviceRef){translateService=(TranslateService)context.getService(serviceRef);}//3、返回結果給用戶resp.setContentType("text/html;charset=GBK");PrintWriter writer=resp.getWriter();if(translateService==null){writer.println("沒有開放翻譯服務!");writer.close();return;}String result=translateService.translate(queryWord);writer.println("結果"+result);writer.close();return;}}其中需要通過MANIFEST.MF引入com.zyg.osgi.translateasslt.service包。
同時,我們要在localTranslateAsslt和remoteTranslateAsslt這兩個插件的Activator中注冊相應的Service,這樣我們的TranslateClient就可以使用它們兩個提供的Service服務了:
package com.zyg.osgi.localtranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.localtranslateasslt.impls.TranslateServiceLocalImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceLocalImpl(), null);System.out.println("本地查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("本地查詢服務已停止!");Activator.context = null;} }
package com.zyg.osgi.remotetranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.remotetranslateasslt.impls.TranslateServiceRemoteImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceRemoteImpl(), null);System.out.println("遠程查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("遠程查詢服務已停止!");Activator.context = null;} }
好的,目前我們的工作基本完成!現在啟動osgi來看看我們的戰果把:
說明我們運行成功了,我們來進入瀏覽器訪問一下我們的靜態頁面:
這說明我們的Web項目起來了,并且靜態資源也訪問成功了。
然后我們來查詢一下單詞,看看我們的Servlet和Service是不是也注冊和實例化成功了:
我們先查本地服務的單詞“USA”的意思
我們再來查詢遠程服務的單詞“cat”的意思
出現這種原因的結果是我們兩個服務都開啟了,但是因為先注冊了Local服務后注冊了Remote服務,二者服務名相同,所以Remote服務把Local服務給覆蓋掉了,那么我們訪問本地Local服務的時候,就訪問不到相應的數據,訪問Remote服務卻可以。
大家可以在看控制臺出入ss,可以看到遠程和本地兩個服務都存在:
我們現在stop掉遠程服務:
因為通過熱部署,我們網站不需要重啟,我們直接訪問遠程服務:
發現遠程已經不能訪問,那么我們訪問本地的服務:
本地服務正常。
當然反過來只用遠程的服務也可以。
所以這體現了一種插件“即插即用”,拔除不影響其他組件的性能。
停止服務,關閉osgi的啟動,我們需要在控制臺中輸入close即可:
以上就是我們利用osgi完成的一個服務可插拔的Web項目。
上面是最原生的方式來注冊服務等,我們下次會介紹依賴注入的方式來對我們的這個Web項目進行改造。
轉載請注明出處:http://blog.csdn.net/acmman/article/details/50916011
總結
以上是生活随笔為你收集整理的【OSGI】4.实战OSGI-翻译助手项目02的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos重启报错Umounting
- 下一篇: paper 46 :中文latex的安装