最近花了点时间看java的OSGi,至于什么是java OSGi呢?我想看这篇文章的你大致心里有个数。我从百度上摘抄了一部分解释,如下:(具体什么是OSGi大家查询相关资料,我这里不多解释)
在具体编写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。
【8】接下来的窗口中。location选中你之前放置 org.eclipse.osgi_3.7.0.v20110613.jar 的路径。我的是 E:\OSGI\equinox 然后点击finish。
【10】最后在TargetPlatform中在你新建的目标上打钩。保存。
【11】下面我们准备启动。在Eclipse中点击Run–>Run configurations…
【13】此时我们准备创建一个项目了。空白处右键–new–other–搜索Plug-in Project。选中之,下一步。
【14】填写上你的项目名称。在TargetPlatform中选中an OSGi framework。再下一步
【15】这一步没太多说的,只需要把jre改成1.7以及以下的即可(用1.8会出问题),然后点击finish。
【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 registrations = new ArrayList();
@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以下的,应该会运行成功。
最后盗以下 静默虚空 的几个知识点。一个是常用的控制台命令。一个是执行流程图。
常用的控制台命令如下: