- OSGi是Open Services Gateway initiative的缩写,叫做开放服务网关协议。容许你动态的启动,停止,安装,删除其中的模块而无需重启服务,至于OSGI的模块层、生命周期层、服务层等的概念网上有很多的文章大概看一下就可以有所了解了,下面我通过一个例子简单的介绍OSGI的应用
- 新建一个plugin in project项目,比如名字叫com.osgi.hellowordl,记得勾选an OSGI framwork,点击下一步,填入ID(helloworld),然后点击完成。新建一个借口Hello 写一个方法sayHello,然后写一个实现类HelloImpl实现sayHello方法。
package com.osgi.helloworld;
public interface Hello {
void sayHello();
}
package com.org.helloworld.impl;
import com.osgi.helloworld.Hello;
public class HelloImpl implements Hello {
private final String message;
public HelloImpl(String message){
this.message = message;
}
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println(this.message);
}
}
接着修改MANIFEST.MF文件把Hello接口暴露给外部模块
增加Export-Package: com.osgi.helloworld;version="1.0"这句
在Activator类start方法中增加注册服务代码,stop卸载服务代码
package com.osgi.helloworld;
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.org.helloworld.impl.HelloImpl;
public class Activator implements BundleActivator {
private static BundleContext context;
private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
registrations.add(context.registerService(Hello.class.getName(), new HelloImpl("欢迎您"), null));
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
for(ServiceRegistration regist : registrations){
System.out.println("unregister"+regist);
regist.unregister();
}
Activator.context = null;
}
}
3. 新建一个client模块 ,com.osgi.helloworldclient项目名,步骤与上个项目一样,ID为helloworldclient.
在MANIFEST.MF文件中导入Hello服务 import-package添加com.osgi.helloworld;version=“1.0”多个模块用逗号分开
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworldclient
Bundle-SymbolicName: helloworldclient
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.osgi.helloworldclient.Activator
Bundle-Vendor: OSGI
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.osgi.helloworld;version="1.0",
org.osgi.framework;version="1.3.0"
Bundle-ActivationPolicy: lazy
修改Activator类 在 启动时候获取Hello服务的引用,通过引用获取sayHello服务,并加入异常处理
package com.osgi.helloworldclient;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.osgi.helloworld.Hello;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
ServiceReference reference = context.getServiceReference(Hello.class.getName());
if(null != reference){
Hello hello = null;
try{
hello = (Hello) context.getService(reference);
if(null != hello){
hello.sayHello();
}
else{
System.out.println("Service:Hello is null");
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally {
context.ungetService(reference);
}
}
else{
System.out.println("Service:Hello not exists");
}
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}
}
4 .点击run configurations选择osgi Framwork新建一个, 随便输入个名字,下面的workspace会出现我们建立的2个项目,选中他。旧版的eclipse只需要osgi一个JAR包就可以运行了, 目前比较新的eclipse需要5个jar包 截图如下 选中它们,然后运行。
运行后输出
欢迎您
osgi>
服务调用成功,你可以使用osgi的一些命令比如ss来查看模块id等信息,stop 加id停止某个模块,start加id启动某个模块,比如我helloworld 的id 是11 运行 stop 11然后再输入ss这个模块的状态从ACTIVE变成了RESOLVED这个时候刷新客户端refresh 10就会提示Hello服务不存在了。