簡而言之, OSGi是一組規范,這些規范允許對使用Java技術構建的軟件進行模塊化組裝。 它定義了組件–服務的創建和注冊(在啟用OSGi的容器中),以便進行內部通信。 OSGi的另一個好處是,所有這些服務都可以在運行時安裝/卸載/啟動/停止(即可以在運行時熱部署代碼)。 與在諸如WebSphere , JBoss , WebLogic的流行J2EE應用服務器中找到的Tomcat和EJB容器之類的Servlet容器實現類似, OSGi也具有諸如Equinox (這是Eclipse的基礎), Apache Felix …等流行的容器實現。
面向服務的方法是OSGi的強項之一,但是當您不得不處理具有大量依賴關系的應用程序時,我覺得這很重要。 OSGi解決了“ Jar Hell”的問題。
一個例子。 假設您在應用程序中使用兩個庫libX和libY。 我們還假設它們每個在libZ中都有一個依賴關系,但是版本不同。 libX取決于libZ 2.0,而libY取決于libZ 1.0 如果libZ 2.0與libZ 1.0不兼容,則在同一應用程序中同時使用它們時,可能會遇到難以解決的問題。 OSGi可以處理此類問題。 OSGi支持Import-Package指令,該指令可用于為應用程序-服務應使用的任何Java包指定一個版本。 OSGi類加載器能夠根據此信息找到正確的包/罐。 在我之前的示例中,如果庫libX,libY和libZ與OSGi兼容,則可以將它們全部加載到同一JVM中而不會出現問題: libZ 1.0將使用Export-Package指令org.libz; 版本= 1.0 libZ 2.0將使用Export-Package指令org.libz; 版本= 2.0 libX將使用Import-Package指令org.libz; 版本= 2.0 libY將使用Import-Package指令org.libz; 版本= 1.0 OSGi還為Java應用程序帶來了更強大的模塊化概念。 只能在捆綁軟件之外使用通過Export-Package指令導出的軟件包。
在本文中,我將解釋使用Eclipse Equinox容器的OSGi 。 在計算機上安裝了Eclipse IDE的任何人也將OSGi容器安裝在Eclipse插件的文件夾中。
OSGi容器jar文件的名稱類似于org.eclipse.osgi_ <version> .jar
您可以像這樣啟動OSGi
java -jar org.eclipse.osgi_3.5.2.R35x_v20100126.jar -console
附件是我如何啟動OSGi容器的示例屏幕截圖(類似于啟動Tomcat )
現在,我們已經啟動了OSGi容器,讓我們使用Maven創建一個“ HelloWorld” OSGi應用程序。 項目結構如下所示:
以下是該項目的pom.xml 。 pom.xml還添加了2個配置文件,以便創建另外2個新模塊( MathService和MathServiceClient ),本文稍后將對此進行說明。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.linkwithweb.osgi</groupId><artifactId>HelloWorld</artifactId><version>0.0.1-SNAPSHOT</version><name>HelloWorld</name><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version></dependency></dependencies><build><finalName>HelloWorld-${version}</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.1</version><configuration><source>1.5</source><target>1.5</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile></archive></configuration></plugin></plugins></build><profiles><profile><id>MathService</id><build><finalName>MathService-${version}</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.1</version><configuration><source>1.5</source><target>1.5</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><excludes><exclude>**/*.xml</exclude><exclude>**/*.bsh</exclude><exclude>**/*.properties</exclude></excludes><archive><manifestFile>src/main/resources/MathService/META-INF/MANIFEST.MF</manifestFile></archive></configuration></plugin></plugins></build></profile><profile><id>MathServiceClient</id><build><finalName>MathServiceClient-${version}</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.1</version><configuration><source>1.5</source><target>1.5</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><excludes><exclude>**/*.xml</exclude><exclude>**/*.bsh</exclude><exclude>**/*.properties</exclude></excludes><archive><manifestFile>src/main/resources/MathServiceClient/META-INF/MANIFEST.MF</manifestFile></archive></configuration></plugin></plugins></build></profile></profiles></project>
如果仔細觀察pom.xml,您將看到我們創建的每個OSGi捆綁包都有3個MANIFEST.MF定義。 這么說,讓我解釋一下OSGi捆綁包是什么。 OSGi軟件包本質上與標準Java“ jar”文件相同,但其特定配置在“ jar的Manifest”文件中定義。 OSGi容器讀取“ jar”的清單文件中的所有OSGi特定條目,以激活捆綁包。 那不是很酷嗎? 使用OSGi,我們避免像其他框架一樣學習任何新的元數據格式!
這是我為MathServiceClient 捆綁包定義的示例Manifest.MF
Manifest-Version: 1.0
Bundle-Name: MathServiceClient
Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
Bundle-SymbolicName: MathServiceClient
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework,com.linkwithweb.osgi.service
如您所見,除Manifest-Version以外的所有條目都是OSGi特定的。 這些條目定義了如何激活捆綁軟件,捆綁軟件的名稱和版本,其所有從屬庫以及暴露給其他服務使用的擴展點。
讓我向您展示如何將“ HelloWorld”捆綁軟件安裝到Equinox OSGi Container中。 以下是“ HelloWorld”捆綁包的MANIFEST.MF文件和Activator類。
package com.linkwithweb.osgi;import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;/*** @author Ashwin Kumar**/
public class HelloActivator implements BundleActivator {public void start(BundleContext context) {System.out.println("Hello World");}public void stop(BundleContext context) {System.out.println("Goodbye All");}
}
Manifest-Version: 1.0
Bundle-Name: HelloWorld
Bundle-Activator: com.linkwithweb.osgi.HelloActivator
Bundle-SymbolicName: HelloWorld
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework
要構建捆綁包,請運行“ mvn clean package”
它將在您的Maven項目的目標文件夾中創建HelloWorld-0.0.1-SNAPSHOT.jar 。 這是顯示如何在Equinox中安裝和啟動“ HelloWorld”捆綁軟件的圖像
如您所見,我們使用install命令安裝捆綁軟件,并使用start命令,使用捆綁軟件安裝后容器返回的捆綁軟件ID啟動捆綁軟件。
現在,就捆綁軟件的生命周期而言,啟動捆綁軟件將觸發對捆綁軟件的Activator類的“ start ”方法的調用,而停止捆綁軟件將觸發對捆綁軟件的Activator類的“ stop ”方法的調用。 我們可以在容器的終端中看到上述行為的結果,該終端在模塊啟動時顯示“ Hello World”消息!
恭喜,您已經了解了OSGi的基礎知識,并且已經部署了第一個捆綁軟件!
曝光和消費服務
為了解釋這一點,我將實現一個非常簡單的示例,在該示例中,我將發布一個可以添加兩個數字的服務。
首先,我們需要定義一個接口,以向外部捆綁包(客戶端)公開“添加”功能
package com.linkwithweb.osgi.service;/*** @author Ashwin Kumar**/
public interface MathService {/*** @param a* @param b* @return*/public int add(int a, int b);
}
現在執行類
package com.linkwithweb.osgi.service;/*** @author Ashwin Kumar**/
public class MathServiceImpl implements MathService {/* (non-Javadoc)* @see com.linkwithweb.osgi.service.MathService#add(int, int)*/public int add(int a, int b) {// TODO Auto-generated method stubreturn a+b;}}
接下來是Activator類,該類將“添加”服務注冊到OSGi容器。
package com.linkwithweb.osgi.service;import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;/*** @author Ashwin Kumar**/
public class MathServiceActivator implements BundleActivator {/** (non-Javadoc)** @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)*/public void start(BundleContext context) {MathService service = new MathServiceImpl();// Third parameter is a hashmap which allows to configure the service// Not required in this examplecontext.registerService(MathService.class.getName(), service, null);System.out.println("Math Service Registered");}/** (non-Javadoc)** @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)*/public void stop(BundleContext context) {System.out.println("Goodbye From math service");}
}
以下是“添加”服務包的清單文件。
Manifest-Version: 1.0
Bundle-Name: MathService
Bundle-Activator: com.linkwithweb.osgi.service.MathServiceActivator
Bundle-SymbolicName: MathService
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework
Export-Package: com.linkwithweb.osgi.service
如果您觀察上面的清單,您會注意到我們正在導出一些軟件包,以便以后使用。 同樣,必須在此處定義所有運行時所需的軟件包(使用Import-Package指令)。
就像本文的上一節一樣,使用以下命令來構建jar文件
mvn -PMathService軟件包
您可以在下面看到安裝和啟動OSGi捆綁軟件的命令。
以下是“添加”服務的使用者的實現。 消費者打包在OSGi捆綁激活器類中,僅用于演示目的。 您可以自由地將使用者作為單獨的OSGi服務實施,因為OSGi服務可以相互通信!
package com.linkwithweb.osgi.service.client;import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;import com.linkwithweb.osgi.service.MathService;/*** @author Ashwin Kumar**/
public class MathServiceClientActivator implements BundleActivator {MathService service;private BundleContext context;/** (non-Javadoc)** @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)*/public void start(BundleContext context) {this.context = context;// Register directly with the serviceServiceReference reference = context.getServiceReference(MathService.class.getName());service = (MathService) context.getService(reference);System.out.println(service.add(1, 2));} /** (non-Javadoc)** @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)*/public void stop(BundleContext context) {System.out.println(service.add(5, 6));}
}
跟隨是“添加”服務使用者捆綁包的清單文件。
Manifest-Version: 1.0
Bundle-Name: MathServiceClient
Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
Bundle-SymbolicName: MathServiceClient
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework,com.linkwithweb.osgi.service
要創建,安裝并啟動“添加”服務客戶端捆綁包,請遵循以下步驟:
mvn -PMathServiceClient軟件包
就這樣! 希望你喜歡它!
您可以在此處下載本文的源代碼
參考:來自Felicitas和Beatitudo博客的 JCG合作伙伴 Aswin的OSGI,適合初學者使用Maven和Equinox(HowTo) 。
- Java Code Geeks Andygene Web原型
- Spring,Quartz和JavaMail集成教程
- 使用Spring將POJO公開為JMX MBean
- 依賴注入–手動方式
翻譯自: https://www.javacodegeeks.com/2011/06/osgi-using-maven-equinox.html