您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
   
 
     
   
 订阅
  捐助
OSGi框架
 
作者昵称:thankjj20160909
  63  次浏览      10
 2021-3-24 
 
编辑推荐:
本文主要介绍了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!!");
}
}

 
   
63 次浏览       10
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析
最新课程计划
 
最新文章
Java虚拟机架构
JVM——Java虚拟机架构
Java容器详解
Java进阶--深入理解ArrayList实现原理
Java并发容器,底层原理深入分析
最新课程
java编程基础到应用开发
JavaEE架构、 设计模式及性能调优
高性能Java编程与系统性能优化
SpringBoot&Cloud、JavaSSM框架
Spring Boot 培训
更多...   
成功案例
国内知名银行 Spring+SpringBoot+Cloud+MVC
北京 Java编程基础与网页开发基础
北京 Struts+Spring
华夏基金 ActiveMQ 原理
某民航公 Java基础编程到应用开发
更多...