编辑推荐: |
本文主要介绍了OSGi框架是什么以及一个简单的案例。
本文来自于csdn,由火龙果软件Anna编辑、推荐。 |
|
1.简介
1.1 what
Open Service Gateway Initiative(OSGi服务平台ServicePlatform)
一个Java框架,可扩展部署和下载的应用程序(bundle)。模块化,可插拔,可动态改变行为,
1.2 advance
Java平台的独立性和动态代码加载能力
1.3 parts
1.3.1 安全层
定义了如何签名和验证一个Bundle
1.3.2 模块层
OSGI的核心层次,定义了Bundle模型,Bundle如何Import和Export代码,以及如何定义和解析Bundle之间的依赖关系
1.3.3 生命周期层
定义了Bundle的生命周期包括的状态以及状态之间如何转换,并且定义了接口支持Bundle的生命周期操作,包括Install,
start, stop, update和uninstall。OSGi提供了Bundle库(BundleRepository)
1.3.4 服务层
定义了如何将一个Java对象注册发布在某个/某些接口下面成为由这些接口表示的服务,获取服务,以及监听某些服务的启动和停止事件等
1.4 application
1.4.1 应用一
一个服务可以是一个网络中的设备,如果一个设备被监测到,则服务可以动态注册;如果设备被移除,则服务能够动态注销。在这样的影响环境汇总编程将耗费大量开销来处理动态性,但是OSCi帮助开发者处理了绝大多数动态性方面的工作。
1.4.2 应用二
用户登录验证模块:要求可动态的替换(系统运行期)用户登录验证的方式。
例如目前有三种验证方式:LDAP验证,DB验证以及配置文件验证;同事要求可随时增加新的验证方式,如CA验证方式等。
1.5 知名OSGi框架
Equinox,成功案例是Eclipse IDE,还有Oscar(不活跃),Knopflerfish
2.Hello World
2.1 New工程
附:这是稍微复杂一点的应用
Zzhello:
public interface
Hello {
public void syaHello();
} |
public class
HelloImpl implements Hello{
final String helloString;
public HelloImpl(String helloString) {
this.helloString = helloString;
}
@Override
public void syaHello() {
System.out.println(this.helloString);
}
} |
Export-Package:
zzhello;version="1.0" |
public class
Activator implements BundleActivator {
private List<ServiceRegistration> r egistrations
=
new ArrayList<>();
public void start (BundleContext context) throws
Exception {
registrations.add(context.registerService(Hello.class.getName(),
new HelloImpl ("Hello, OSGi"), null));
System.out.println ("OSGi-服务注册成功");
}
public void stop (BundleContext context) throws
Exception {
for (ServiceRegistration registration: registrations){
registration.unregister();
System.out.println ("取消服务注册:"+registration);
}
}
} |
ZzhelloClient:
Bundle-Activator: zzhelloclient.HelloUser
Import-Package: org.osgi.framework;version ="1.3.0",
zzhello;version="1.0.0" |
public class
HelloUser implements BundleActivator{
@Override
public void start (BundleContext ctx) throws Exception
{
ServiceReference reference = ctx.getServiceReference
(Hello.class.getName());
if (reference != null) {
Hello hello = null;
try {
hello = (Hello)ctx.getService(reference);
if(hello != null)
hello.syaHello();
else
System.out.println ("Services:Hello---object
null");
} catch (Exception e) {
e.printStackTrace();
}finally {
ctx.ungetService (reference);
hello = null;
}
}else {
System.out.println ("Service:Hello---not
exists");
}
}
@Override
public void stop (BundleContext arg0) throws Exception
{
}
|
2.2 Debug环境Configuration设置(全选的话会报错)
2.3 结果
类似的命令还有install,uninstall等
3.Bundle
OSGi中所有模块的部署都必须以Bundle方式来进行部署,Bundle以jar包形式存在的一个模块化物理单元,里面包含了代码、资源文件和元数据(metadata),并且jar包的物理边界也同时是运行时逻辑模块的封装边界。
这个jar和普通jar唯一不同点就是MANIFEST.MF,关于Bundle的所有信息都在其里面进行了描述(如Bundle名称、需要导入的包,输出的包等),官方称为bundle的元数据。
3.1 类加载机制
在使用一个bundle之前,必须对共享的包之间的约束关系进行解析。解析过程就是确定导入包如何连接到导出包。解析过程必须在bundle中任何代码加载或运行之前。
在多数Java应用中,通常是由一个Class Loader来加载所有的类和资源文件,而在OSGi模块层中(一个模块就是一个Bundle)则为每个模块提供了各自的Class
Loader,从而保证了模块的闭合,同时为模块的关联提供控制
3.2 生命周期
Bundle通过实现BundleActivator接口去控制其生命周期
3.2.1 Bundle六种状态
1)installed:Bundle已经成功安装
2)resolved:Bundle所需要的类都已经可用了,该状态表明Bundle已经准备好了用于启动或者说Bundle已经被停止
3)starting:Bundle正扎起启动中,BundleActivator的start方法已经被调用不过还没返回
4)active:Bundle已启动,并在运行中
5)stopping:Bundle正在停止中,BundleActivator的stop方法已经被调用,不过还没返回
6)uninstalled:Bundle已经被卸载了
API由以下三个核心接口组成
1) BundleActivator:捕捉到bundle的start和stop事件
2) BundleContext:一个bundle在框架中的执行时上下文,当启动或停止一个bundle的时候,框架将它发送到一个bundle的激活器
3) Bundle:包含bundle基本信息和bundle生命周期的控制接口
3.3 Bundle引用
Bundle是个独立概念,在OSGi框架中对于每个Bundle采用的是独立的classloader机制,这也就意味着不能采用传统的引用其他Bundle工程来实现Bundle间的协作,
3.1.1 定义输出的包以及引用的包
每个Bundle可以定义输出的包以及引用的包,这样在Bundle间就可以共享包中的类,但在OSGi、框架中更推荐采用Service方式。
3.1.2 Service方式
Bundle通过BundleContext注册对外提供的服务,同事也可以通过BundleContext来获得需要引用的服务。
3.1.3 Bundle相互调用
两个bundle互相引用对方的包会报错(循环引用),项目会出现红色感叹号
3.4 三种特殊的Bundle
3.4.1 Require Bundles
并不特殊,只是可以直接被其他Bundle通过Require-Bundle来使用的Bundle
3.4.2 Fragment Bundles
本身不拥有独立的classloader,可以看成是Bundle的一种附属,片段。片段的关键用途是提供不同区域的翻译文件,这样就可以实现翻译文件从主要应用的bundle中独立出来。可以用来夸张host
bundle的功能,做一些bundle的依赖类
--> New Fragment Project
启动后会发现片段不能够自己启动
主Bundle代码:
public class Activator implements BundleActivator
{
// 去读配置文件,默认就是读主啊,为什么网上会说从会覆盖掉主呢???
public void start (BundleContext context) throws
Exception {
InputStream is = Activator.class.getResourceAsStream ("/META-INF/ myConfig.properties");
Properties properties = new Properties();
properties.load(is);
System.out.println ("name"+properties.getProperty ("name"));
}
public void stop (BundleContext context) throws
Exception {
System.out.println ("Goodbye World!!");
}
}
|
|