OSGI学习系列(四)类的加载

来源:互联网 发布:ubuntu常用命令行 编辑:程序博客网 时间:2024/05/18 19:20

osgi一个最大的特色就是使用不同的ClassLoader,让多个bundle共享一个虚拟机,而每一个bundle使用单独的ClassLoader

如下图所示:
   
对于资源和类的装载主要包括以下三种途径:
Boot classpath:启动类环境,包括java.*包和相应的实现包。
Framework classpath:osgi框架拥有一个独立的ClassLoader,用于装载框架接口类,以及相应的实现类。
Bundle Space:每个bundle包括了与bundle相关的jar文件,以及相关的资源。

对于一个类的查询,主要通过以下途径进行查询:
1.从Parent ClassLoader中装载
2.从Import Package中查询类路径。
3.从Required bundles中查询类
4.自身bundle,相关ClassPath
5.相关的插件片段Fragment。
如下图
   
这么说起来,还是比较的抽象,还是从一个实例来具体的分析。
假设有如下Bundle,
相关的描述文件如下:

Java代码  收藏代码
  1. Bundle:org.zframework.core  
  2. Manifest-Version: 1.0  
  3. Bundle-Name: core  
  4. Bundle-SymbolicName: org.zframework.core;singleton:=true  
  5. Bundle-ClassPath: .  
  6. Import-Package: net.sf.ehcache;version="1.3.0",  
  7.  net.sf.ehcache.config;version="1.3.0",  
  8.  net.sf.ehcache.event;version="1.3.0",  
  9.  org.osgi.framework;version="1.4.0",  
  10.  org.osgi.service.log;version="1.3.0",  
  11.  ...  
  12. Require-Bundle: org.eclipse.equinox.common;visibility:=reexport,  
  13.  ...  
  14. Export-Package: org.zframework.core;version="1.0.0",  
  15.  ...  
 



现在创建了如下的类:

Java代码  收藏代码
  1. package org.zframework.core;  
  2. import java.net.URL;  
  3. import java.util.Collection;  
  4. import net.sf.ehcache.Cache;  
  5. import net.sf.ehcache.CacheManager;  
  6. import net.sf.ehcache.Element;  
  7. import org.osgi.framework.BundleContext;  
  8. public class EhCacheManager extends AbstractCacheManager implements  
  9.     BundleContextAware {  
  10.     private String cacheFile;  
  11.     private BundleContext context;  
  12.     private CacheManager manager;  
  13.     public Cache getCache(String cacheName) {  
  14.     Cache cache = manager.getCache(cacheName);  
  15.     if (cache == null) {  
  16.           ...  
  17.     }  
  18.     return cache;  
  19.     }  
  20.     ...  
  21. }  
 


假设有一个Bundle org.zframework.model需要使用此类,描述如下:

Java代码  收藏代码
  1. Manifest-Version: 1.0  
  2. Bundle-Name: model  
  3. Bundle-SymbolicName: org.zframework.model;singleton:=true  
  4. Bundle-ClassPath: .  
  5. Import-Package: javax.persistence;version="1.0.0",  
  6.   javax.persistence.spi;version="1.0.0",  
  7.   org.osgi.framework;version="1.4.0",  
  8.   ...  
  9.  Require-Bundle: org.zframework.core  
  10.   
  11. 类Model  
  12. package org.zframework.model;  
  13. import java.net.URL;  
  14. import java.util.Collection;  
  15. import org.zframework.core.EhCacheManager ;  
  16. public class Model{  
  17.     private EhCacheManager manager;  
  18.     public Object getCache(String key) {  
  19.     Object o = manager.getCache(key);  
  20.     return o;  
  21.     }  
  22.     ...  
  23. }  
 


下面简单说明一下装载过程:
在装载Model类时,
1.对于java.*类的装载,由相应的Boot ClassLoader 装载
2.装载EhCacheManager,
       1.在Import-Package中查询是否存在匹配中的org.zframework.core包声明,如果有,则委派给org.zframework.core包声明的Bundle进行装载,本例没有,则继续。
       2.在Require-Bundle中查询所有的Export声明包,判断是否存在org.zframework.core匹配。本例中,应该存在。如果不存在,则执行步骤2.3
       3.查询本bundle的类路径,是否有此类存在。不存在,继续2.4步骤
       4.查询所有的fragments bundle(特殊的bundle) 类路径。不存在,继续2.5步骤
       5.判断是否使用DynamicImport-Package: * 声明,如果是则查询所有的bundle中声明的Export包。如果还是不存在,则抛出ClassNotFound例外。
关于DynamicImport-Package: * ,这是比较极端的设置,一般不会推荐使用,主要破坏了相关的封装性。



/**  

 *引用自这篇文章

 * http://zyl.iteye.com/blog/334326

 */


0 0
原创粉丝点击