OSGi依赖性管理:Bundle访问域

来源:互联网 发布:创意字体软件 编辑:程序博客网 时间:2024/05/18 00:01

OSGi允许您把您的应用程序分成多个模块,并能管理这些模块之间的依赖性。本文介绍了OSGi依赖性管理的概念。

本文是《你好,OSGi》系列的第三部分。下面介绍OSGi依赖性管理。

OSGi依赖性管理

OSGi允许您把您的应用程序分成多个模块,并能管理这些模块之间的依赖性。为了达到这个目的,它引入了Bundle访问域的概念。Bundle中类的缺省访问范围只对本Bundle内部可见,但对其它任何Bundle都是不可见的;在Bundle内部,类的可访问性遵循Java语言的一般规范。那么,您如果想要从一个Bundle中访问另一个Bundle中的类,您应该怎么办呢?解决方法是将源Bundle中的包导出来,然后把它们导入到目标Bundle中。在本小结中,我们将通过一个示例程序说明这个概念。

首先,我们新建一个名com.javaworld.sample.HelloService的Bundle,并从其中导出一个包,然后将该包导入到我们的com.javaworld.sample.HelloWorld Bundle中。

4.1. 导出Java包

我们开始新建一个com.javaworld.sample.HelloServiceBundle,并从其中导出一个Java包,具体步骤如下:

1) 新建com.javaworld.sample.HelloService Bundle,具体步骤请参见上小节中新建com.javaworld.sample.HelloWorldBundle的步骤;

2) 在HelloService Bundle中,新建一个com.javaworld.sample.service.HelloService.java接口,其源代码如清单3所示。

源代码清单3. HelloService.java

  1. package com.javaworld.sample.service;  
  2. public interface HelloService {  
  3. public String sayHello();  
  4. }  
  5.  

3) 新建类com.javaworld.sample.service.impl.HelloServiceImpl.java,该类实现HelloService接口,其源代码如清单4所示。

源代码清单4. HelloServiceImpl.java

  1. package com.javaworld.sample.service.impl;  
  2. import com.javaworld.sample.service.HelloService;  
  3. public class HelloServiceImpl implements HelloService {  
  4. public StringsayHello() {  
  5. System.out.println("InsideHelloServiceImple.sayHello()");  
  6. return"Say Hello";  
  7. }  
  8. }  
  9.  

4) 请在您的Eclipse Manifest编辑器中打开HelloService包中的MANIFEST.MF文件,点击“Runtime(运行时)” 标签,在“导出包”小节,单击“Add(添加)”按钮,并选择com.javaworld.sample.service包。这时,HelloServiceBundle中的MANIFEST.MF文件代码应如源代码清单5所示。

源代码清单5. HelloService Bundle中的Manifest文件

  1. Manifest-Version: 1.0 
  2. Bundle-ManifestVersion: 2 
  3. Bundle-Name: HelloService Plug-in  
  4. Bundle-SymbolicName:com.javaworld.sample.HelloService  
  5. Bundle-Version: 1.0.0 
  6. Bundle-Vendor: JAVAWORLD  
  7. Bundle-Localization: plugin  
  8. Export-Package: com.javaworld.sample.service  
  9. Import-Package:org.osgi.framework;version="1.3.0" 
  10.  

您可以看到,HelloService Bundle中的MANIFEST.MF文件和HelloWorldBundle非常相似,唯一的区别就是多了一个Export-Package属性头,该属性头的值为com.javaworld.sample.service;Export-Package属性头通知OSGi容器,其它Bundle可以从HelloService Bundle外面访问com.javaworld.sample.service包中的类。请注意,在示例代码中,我们只暴露了接口类HelloService,而没有暴露其实现类的HelloServiceImpl。

4.2. 导入Java包

下面,我们将从HelloServiceBundle中导出的com.javaworld.sample.service包并将其导入到HelloWorldBundle中,具体步骤如下:

1). 请在com.javaworld.sample.HelloWorld Bundle中找到MANIFEST.MF文件,并在Manifest编辑器中打开,点击“Dependencies(依赖性)”标签,然后点击“ImportPackage(导入包)”按钮,将com.javaworld.sample.service添加为导入包,这时,您的HelloWorldBundle中的MANIFEST.MF文件内容应如源代码清单6所示:

源代码清单6. HelloWorld Bundle中的MANIFEST.MF文件

  1. Manifest-Version: 1.0 
  2. Bundle-ManifestVersion: 2 
  3. Bundle-Name: HelloWorld Plug-in  
  4. Bundle-SymbolicName: com.javaworld.sample.HelloWorld  
  5. Bundle-Version: 1.0.0 
  6. Bundle-Activator: com.javaworld.sample.helloworld.Activator  
  7. Bundle-Vendor: JAVAWORLD  
  8. Bundle-Localization: plugin  
  9. Import-Package: com.javaworld.sample.service,  
  10. org.osgi.framework;version="1.3.0" 
  11.  

从上面的代码可以看出,Import-Package属性头的值是一个由逗号分隔的字符串,这是您想导入包的列表。在HelloWorldBundle示例代码中,我们引入了两个包,即com.javaworld.sample.service和org.osgi.framework。

org.osgi.framework包中包含有OSGi框架类,比如,在HelloWorldBundle中的Activator.java中用到的BundleContext和BundleActivator类都属于这个包。

2) 下面,请在Eclipse Java编辑器中打开com.javaworld.sample.helloworld.Activator.java,您会注意到,您现在可以访问HelloService接口,但不能访问HelloServiceImpl实现类,这是因为HelloServiceBunlde只导出了com.javaworld.sampel.service包,同时HelloWorldBundle也导入了这个包。HelloServiceImpl是HelloServiceBundle的一个内部类,任何其它的Bundle都不能访问它。

4.3. 类级别上的访问域

如果您运行示例的HelloService服务包,它会在Eclipse控制台上打印出”HelloWorld”。但是,如果您想在HelloWorld Bundle的Activator中访问HelloServiceImpl类,这时,编译没有问题,但在OSGi容器中运行这个Bundle时会抛出异常。

OSGi容器是如何能将jar文件中的一些类隐藏掉,而让另外一些类可见呢?这是因为OSGi容器使用Java类加载器来管理类的可见性,OSGi容器为每个Bundle创建不同的类加载器,因此每个Bundle能访问位于下列位置中的类:

a) 位于Java启动类路径下的、所有以Java.*开头的包中的类;

b) 位于OSGi框架类路径下的类,通常有一个独立的类加载器负责加载框架的实现类及关键的接口类;

c) 位于Bundle空间中的类,这些类通常包含在与Bundle相关的jar文件中,以及加到这个Bundle中的其它jar包中的类。

d) 导入包中的类,例如,HelloWorld Bundle导入了com.javaworld.sample.service包,因此它能访问该包中的类。Bundle级别的访问域是OSGi一个非常强大的功能,例如,它可以让您安全地更新HelloServiceImpl.java类,而不必担心依赖于这个类的代码受到破坏。

以上就大概介绍了OSGi依赖性管理的概念。

转自:http://developer.51cto.com/art/200909/152333.htm

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 25岁总掉头发怎么办 25岁掉头发厉害怎么办 我25岁经常掉头发怎么办 25岁掉头发很厉害怎么办 我今年25岁掉头发怎么办 头顶头发稀少怎么办有方法吗 头发又干又黄怎么办 2岁宝宝头发细软怎么办 头发突然变得稀疏了怎么办 孕期掉头发很厉害怎么办 冬天头发掉的厉害怎么办 怀孕期间掉头发比较严重怎么办 头发油腻容易掉发怎么办 最近头发掉的厉害怎么办 头发新长的绒毛怎么办 久躺床上头发黏在一起怎么办 头发长油怎么办小妙招 头发出油多脱发怎么办 头发出油掉头发怎么办 在英国狂掉头发怎么办 我头发油头皮痒脱发怎么办 油性头发容易掉发怎么办 洗了头发很蓬松怎么办 小孩头皮黄掉头发怎么办 头发又油又掉发怎么办 英国的水掉头发怎么办 洗发为什么会掉头发怎么办 头发老掉怎么办吃什么 19岁掉头发严重怎么办 头发总是从根掉怎么办 18岁掉头发很厉害怎么办 20岁脱发严重该怎么办 22岁m型脱发严重怎么办 22掉头发很厉害怎么办 哺乳期头发掉的很厉害怎么办 失眠多梦掉头发怎么办 老婆生完孩子掉头发怎么办 16岁发际线高怎么办 生了小孩头发掉怎么办 16岁头发掉的厉害怎么办 经常脱发严重不长头发怎么办