本文介紹了用Idea搭建OSGI項目開發的過程,演示使用的JDK8,Equinor OSGI Framework。java
OSGI的全稱是Open Service Gateway Initiative,直譯就是開放服務網關。最新的OSGI定義是The Dynamic Module System for Java,即面向java的動態模塊化系統。
在傳統Web開發中,咱們爲了進行功能的分離,常常會進行模塊劃分,好比基礎信息模塊交由A和B作,接口信息模塊交由C和D作。最終,再聚集到一塊兒,組成一個完整的項目。在這整一個流程中,咱們作到的只是邏輯上的解耦,最終這些模塊仍是運行於同一服務器上,共享同一個classpath。這時就會出現一個侷限性問題,好比如今接口規範改了,我只想停掉接口信息模塊,而基礎信息模塊仍能正常運行,這顯然是沒法實現的。而使用OSGI能夠完美解決這個問題,OSGI是基於模塊(Bundle)驅動的,每一個模塊都有屬於本身的classpath和類加載器,模塊之間經過服務註冊和發現進行關聯,每一個模塊有着本身獨立的生命週期,咱們能夠動態地對模塊進行加載、卸載、更新。摘自https://www.jianshu.com/p/11d...。
OSGI能夠理解成是JVM單進程內的SOA,固然也支持多進程分佈式的模塊之間的調用。api
下載地址:https://download.eclipse.org/...
本文下載的是equinox-SDK-4.11.zip,下載後進行解壓,後面須要用到這個解壓目錄。服務器
File -> New -> Project,選擇Java,點擊Next,建立一個空工程。
繼續點擊Next。
填寫項目名稱,這裏叫osgi_demo。框架
分別建立api、server、client三個OSGI模塊。
建立模塊時勾選OSGI做爲開發環境,Use library從剛纔下載的Equinox解壓的目錄下的plugins目錄中選擇org.eclipse.osgi_3.13.300.v20190218-1622.jar。
建立模塊完成以後,打開idea的preferences,在Languages & Frameworks找到OSGI Framework Instances選項。
添加Equinox,Home directory選擇剛纔解壓的Equinox目錄。eclipse
結構以下圖
api模塊中定義接口類IHelloService分佈式
package osgi.demo.api; public interface IHelloService { /** * 和某人打招呼 * @param somebody * @return */ String sayHello(String somebody); }
server模塊接口實現類HelloServiceImplide
package osgi.demo.server; import osgi.demo.api.IHelloService; public class HelloServiceImpl implements IHelloService { @Override public String sayHello(String somebody) { return "hello " + somebody; } }
server模塊服務註冊類HelloServerBundle模塊化
package osgi.demo.server; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import osgi.demo.api.IHelloService; import java.util.Dictionary; import java.util.Hashtable; public class HelloServerBundle implements BundleActivator { @Override public void start(BundleContext bundleContext) throws Exception { IHelloService service = new HelloServiceImpl(); Dictionary<String , Object> properties = new Hashtable<>(); //服務註冊 bundleContext.registerService(IHelloService.class, service, properties); } @Override public void stop(BundleContext bundleContext) throws Exception { } }
client模塊調用服務類HelloClientBundleui
package osgi.demo.client; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import osgi.demo.api.IHelloService; import java.util.Objects; public class HelloClientBundle implements BundleActivator { @Override public void start(BundleContext bundleContext) throws Exception { //獲取到IHelloService服務引用 ServiceReference<IHelloService> reference = bundleContext.getServiceReference(IHelloService.class); if (Objects.nonNull(reference)) { //發現服務 IHelloService service = bundleContext.getService(reference); if (Objects.nonNull(service)) { System.out.println(service.sayHello("jecyhw")); } //註銷服務 bundleContext.ungetService(reference); } } @Override public void stop(BundleContext bundleContext) throws Exception { } }
api模塊配置,導出接口定義所在包osgi.demo.api(Additional properties是bundle的相關屬性配置的地方)。
server模塊配置,配置HelloServerBundle類做爲該bundle的啓動類。
client模塊配置,配置HelloClientBundle類做爲該bundle的啓動類。idea
選擇Edit Configurations。
添加OSGI Bundles。
配置以下。
client模塊調用了server的服務,按照依賴關係,server模塊須要先啓動,把服務註冊在osgi框架中,client模塊才能調用到,Start level是用來定義bundle模塊的啓動優先級,值越小,啓動優先級越高。
Framework start level是整個osgi框架的啓動級別,也就是整個項目的啓動級別,大於這個值的bundle模塊是不會被啓動的。若是這個值爲1,client模塊的啓動級別爲2,client模塊是不會被啓動的,能夠調整試試。
點擊OK以後,就能夠運行了。
運行結果截圖。
Java模塊化之路 —— OSGI介紹深刻理解OSGi:Equinox原理、應用與最佳實踐