OSGI實現服務註冊於發現

發佈和使用服務

由於 OSGi 框架能夠方便的隱藏實現類,所以對外提供接口是很自然的事情,OSGi 框架提供了服務的註冊和查詢功能。好的,那麼我們實際操作一下,就在 Hello world 工程的基礎上進行。

我們需要進行下列的步驟:

  1. 定義一個服務接口,並且 export 出去供其它 bundle 使用;
  2. 定義一個缺省的服務實現,並且隱藏它的實現;
  3. Bundle 啓動後,需要將服務註冊到 felix 框架;
  4. 從框架查詢這個服務,並且測試可用性。

直接上代碼,主pom的xml文件

<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.renming.osgi.helloworld</groupId>
  <artifactId>helloworld</artifactId>
  <version>1.0.0</version>
  <modules>
    <module>server</module>
    <module>client</module>
  </modules>
  <packaging>pom</packaging>

  <name>helloworld</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.renming.osgi.helloworld</groupId>
        <artifactId>server</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>org.eclipse</groupId>
        <artifactId>osgi</artifactId>
        <version>3.9.1-v20130814-1242</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

server的pom文件

<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">
    <parent>
        <artifactId>helloworld</artifactId>
        <groupId>com.renming.osgi.helloworld</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>server</artifactId>
    <packaging>bundle</packaging>

    <name>server</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>osgi</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-SymbolicName>$(replace;${project.artifactId};-;_)</Bundle-SymbolicName>
                        <Export-Package>
                            com.renming.osgi.helloworld.server.inter;version="${project.version}"
                        </Export-Package>
                        <Import-Package>org.osgi.framework</Import-Package>
                        <Bundle-Activator>com.renming.osgi.helloworld.Activator</Bundle-Activator>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

client的pom文件

<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">
    <parent>
        <artifactId>helloworld</artifactId>
        <groupId>com.renming.osgi.helloworld</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>client</artifactId>
    <packaging>bundle</packaging>

    <name>client</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.renming.osgi.helloworld</groupId>
            <artifactId>server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>osgi</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-SymbolicName>$(replace;${project.artifactId};-;_)</Bundle-SymbolicName>
                        <Import-Package>
                            org.osgi.framework,com.renming.osgi.helloworld.server.inter;version="${project.version}"
                        </Import-Package>
                        <Bundle-Activator>com.renming.osgi.helloworld.Activator</Bundle-Activator>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

server的java代碼目錄如下:

clent的java代碼目錄如下:

其中server中的Activator的java代碼如下:

package com.renming.osgi.helloworld;

import java.util.ArrayList;
import java.util.List;

import com.renming.osgi.helloworld.server.impl.HelloImpl;
import com.renming.osgi.helloworld.server.inter.Hello;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

public class Activator implements BundleActivator {

    private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();

    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }

    @Override
    public void start(BundleContext bundleContext) throws Exception {
        Activator.context = bundleContext;
        System.out.println("----------------hello start---------------------");
        //註冊hello接口中的服務
        registrations.add(bundleContext.registerService(Hello.class.getName(), new HelloImpl("Hello, OSGi"), null));
        System.out.println("----------------hello start---------------------");
    }

    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        Activator.context = null;
        for (ServiceRegistration registration : registrations) {
            System.out.println("unregistering: " + registration);
            registration.unregister();
        }

    }

}

clent中的Activator的java代碼如下:

package com.renming.osgi.helloworld;


import com.renming.osgi.helloworld.server.inter.Hello;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

public class Activator implements BundleActivator {

    @Override
    public void start(BundleContext ctx) {
        System.out.println("----------------hello client start---------------------");
        ServiceReference ref = ctx.getServiceReference(Hello.class.getName());
        if (ref != null) {
            Hello hello = null;
            try {
                hello = (Hello) ctx.getService(ref);
                if (hello != null) {
                    hello.sayHello();
                }else {
                    System.out.println("Service:Hello---object null");
                }
            } catch (RuntimeException e) {
                e.printStackTrace();
            } finally {
                ctx.ungetService(ref);
                hello = null;
            }
        } else {
            System.out.println("Service:Hello---not exists");
        }
        System.out.println("----------------hello client start---------------------");
    }

    @Override
    public void stop(BundleContext ctx) throws Exception {

    }

}

server中主要是對某個服務進行註冊的操作,其中註冊的方法主要如下:

 //註冊hello接口中的服務
        registrations.add(bundleContext.registerService(Hello.class.getName(), new HelloImpl("Hello, OSGi"), null));

實際註冊的是hello接口的實現類HelloImpl

OSGI的運行:

這裏我們採用的是felix的具體實現的OSGI

下載felix  https://mirrors.tuna.tsinghua.edu.cn/apache//felix/org.apache.felix.main.distribution-6.0.0.zip

拷貝bin、bundle、conf到當前工程,也可自行建目錄。

運行felix項目:java -jar bin/felix.jar

若未報錯並出現g!。然後執行命令行 lb 得到如下控制檯輸出信息。

安裝如上項目打包好的文件 server-1.0.0.jar、clent-1.0.0.jar

最後控制檯輸出Hello, OSGI。由此一個簡單的基於OSGI框架的服務註冊和發現。

發佈了15 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章