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框架的服务注册和发现。

猜你喜欢

转载自blog.csdn.net/liangkun_java/article/details/81084900