- 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服务不存在了。