【java】java OSGi初体验

最近花了点时间看java的OSGi,至于什么是java OSGi呢?我想看这篇文章的你大致心里有个数。我从百度上摘抄了一部分解释,如下:(具体什么是OSGi大家查询相关资料,我这里不多解释)

ogsi解释

在具体编写OGSi的代码之前。我查阅了几篇资料,写得蛮好的,分别是:
1、【OSGi 基本原理】http://www.cnblogs.com/jingmoxukong/p/4546947.html
PDF下载地址:OSGi基本原理 pdf文档
2、【OSGI入门篇:模块层】http://osgi.com.cn/article/7289219
PDF下载地址:【OSGI入门篇:模块层 pdf文档】
3、【OSGi入门篇:生命周期层】http://osgi.com.cn/article/7289216
PDF下载地址: 【OSGI入门篇:生命周期层】
4、【OSGi入门篇:服务层】http://osgi.com.cn/article/7289220
PDF下载地址:OSGi入门篇:服务层
5、【OSGi入门篇:开发环境建立和Hello World】http://osgi.com.cn/article/7289228
PDF下载地址:OSGi入门篇:开发环境建立和Hello World

看完后,我也动手创建了一个项目,测试了下。下面记录我的过程。
【1】先下载Equinox开发包。下载地址:http://archive.eclipse.org/equinox/ 或者直接从这里下载(带源码):org.eclipse.osgi_3.7.0.v20110613.jar及源码。为了方便,我下载的版本是和 静默虚空 的版本相同(其实我最开始下载了一个较新的版本,结果运行不对)。截图如下:
这里写图片描述

【2】将下载好的 org.eclipse.osgi_3.7.0.v20110613.jar 文件放到本地。比如我的放置在E:\OSGI\equinox
示例

【3】打开运行控制窗口,用命令切换到你放置org.eclipse.osgi_3.7.0.v20110613.jar的文件夹, 然后输入命令:

java -jar org.eclipse.osgi_3.7.0.v20110613.jar -console

【其中org.eclipse.osgi_3.7.0.v20110613.jar是你下载的jar包】
如果运行窗口显示了 osgi> 表示运行成功。
示例

【4】现在我们准备将这个jar集成到Eclipse中来使用。我们先打开一个Eclipse(最好是新的,不要用你常用的Eclipse,怕搞坏了)。点击Window->Preferences。选中Plug-in Development,再选中Target Platform,然后点击Add。
示例

【5】在弹出的窗口使用默认设置:Nothing:start with an empty target definition,然后next。
示例

【6】接下来的窗口点击add。
示例

【7】接下来的窗口选中Directory,然后next。
示例

【8】接下来的窗口中。location选中你之前放置 org.eclipse.osgi_3.7.0.v20110613.jar 的路径。我的是 E:\OSGI\equinox 然后点击finish。
这里写图片描述

【9】接下来的窗口如下:点击finish。
示例

【10】最后在TargetPlatform中在你新建的目标上打钩。保存。
示例

【11】下面我们准备启动。在Eclipse中点击Run–>Run configurations…
详情

【12】点击运行后,我们控制台会有如下的信息。表示成功了。
示例

【13】此时我们准备创建一个项目了。空白处右键–new–other–搜索Plug-in Project。选中之,下一步。
示例

【14】填写上你的项目名称。在TargetPlatform中选中an OSGi framework。再下一步
示例

【15】这一步没太多说的,只需要把jre改成1.7以及以下的即可(用1.8会出问题),然后点击finish。
示例

【16】创建完毕后,截图如下。
示例

【17】现在我们创建一个接口(包名是com.lanting),以及一个实现类(包名是com.lanting.impl)。代码如下:

package com.lanting;

public interface Hello {
    void sayHello();

}
package com.lanting.impl;

import com.lanting.Hello;

public class HelloImpl implements Hello {

    private String helloString;

    public HelloImpl(String helloString) {
        this.helloString = helloString;
    }

    @Override
    public void sayHello() {
        System.out.println(this.helloString);

    }

}

**为了将这个接口暴露出来,我们需要在MANIFEST文件中加入如下条目:

Export-Package: com.lanting;version="1.0"

【18】我们再创建一个生命周期模块(Activator),包名是com.lanting.activator,代码如下:

package com.lanting.activator;

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

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

import com.lanting.Hello;
import com.lanting.impl.HelloImpl;

public class Activator implements BundleActivator {

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

    @Override
    public void start(BundleContext ctx) throws Exception {
    // 这里我们注册了一个HelloImpl实例,并传入构造方法 hello OSGI 参数
        registrations.add(ctx.registerService(Hello.class.getName(), new HelloImpl("hello OSGI"),null));

    }

    @Override
    public void stop(BundleContext ctx) throws Exception {
        for(ServiceRegistration r : registrations) {
            System.out.println("取消注册:"+r);
            r.unregister();
        }
    }

}

**为了让这个Activator能够工作,需要在MANIFEST文件中做如下定义:

Bundle-Activator: com.lanting.activator.Activator

到最后,我的MANIFEST文件的内容如下:

ManifestVersion: 2
Bundle-ManifestVersion: 2
Bundle-Name: Hello
Bundle-SymbolicName: hello
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Activator: com.lanting.activator.Activator
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.lanting;version="1.0"

【19】我们准备再新建一个项目,在新建的项目去获取并执行sayHello()。我们与从【13】开始一样的流程,再创建一个名为:MyClient的项目。创建完毕后如下:
示例

【20】为了使用我们刚刚创建的hello工程中的Hello,我们应该在MyClient工程的MANIFEST中申明。申明代码如下:(其中com.lanting是我们之前hello工程创建的包,逗号分隔后的包是自带的,我们暂时不管,多个包就是以逗号分隔,分号分隔是扩展信息。)

Import-Package: com.lanting,org.osgi.framework;version="1.3.0"

【21】我们申明完后,就可以使用hello工程中的对应的包了。我们再在MyClient中创建一个Activator去看看能不能调用并执行我们在【18】步传入的HelloImpl实例。代码如下:

package com.lanting.client;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import com.lanting.Hello;

public class HelloUser implements BundleActivator {

    @Override
    public void start(BundleContext ctx) throws Exception {
    // 从BundleContext中获取注册的Hello实例。
        ServiceReference ref = ctx.getServiceReference(Hello.class.getName());
        // 如果注册过这个实例,将不为空。
        if (ref != null) {
            Hello hello = null;
            try {
            // 从引用中获取到具体的Hello的实现类(也就是从【18】步中注册的)
                hello = (Hello) ctx.getService(ref);
                if (hello != null) {
                // 调用sayHello方法
                    hello.sayHello();
                } else {
                    System.out.println("hello为空");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ctx.ungetService(ref);
                hello = null;
            }
        } else {
            System.out.println("ref为空");
        }
    }

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

    }

}

【22】最后选择Run–Run configurations…。从图中我们可以看到,WorkSpace中多了我们创建的两个工程。点击run,执行。如果之前你创建的jre是在1.8以下的,应该会运行成功。
实例

【23】运行结果如下:可以看出。我们成功执行了该实例
实例


最后盗以下 静默虚空 的几个知识点。一个是常用的控制台命令。一个是执行流程图。
常用的控制台命令如下:
常用控制台命令

例如我可以简单显示所有bundle的状态,我们就可以在控制台输入:ss
示例

执行流程图如下:
执行流程图

猜你喜欢

转载自blog.csdn.net/lantingshuxu/article/details/78202397