OSGi依赖性管理:Bundle访问域

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值