`
shutiao2008
  • 浏览: 212001 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring-DM笔记之osgi:reference

阅读更多
  现下osgi可谓是一个比较有人气的方向,它为应用系统带来了强大的动态解决方案。在某些程度上osgi同Maven、Antx十分相似,它们都提供了版本化条件化的引用系统,让我们在编译期、运行期拥有更加大的灵活性。同样的思想也可以运用在IOC的实现上,现在主流的IOC一般以名称、类型作为引用依赖定位的依据,并且带有强烈的一对一基数限制,spring-dm的出现将osgi强大的动态能力很自然地集成到IOC容器中,使之易于使用又具备很高的灵活性。

  在整合spring和osgi的过程中,要做的很重要的一件事情就是如何将osgi的service引入到spring的管理体系中来。在spring一般依据属性(字段)的名字来确定这个属性的(字段)运行期注入物,但是在osgi的service体系下,光靠简单的名称或者类型来过滤符合条件的service,可能会得到好几个候选对象,这同spring的依赖解析是有矛盾的。再加上osgi的动态性,service的生命周期比较复杂,符合条件的service可能随时会被卸载,当然也可能有新的符合条件的service不知道什么时候就出现了。

  在spring-dm中,OsgiNamespaceHandler负责解释所有同osgi相关的xml片段。用于解释导入osgi服务相关的主要有以下代码:
  registerBeanDefinitionParser(”reference“, new ReferenceBeanDefinitionParser());
  registerBeanDefinitionParser(”list“, new CollectionBeanDefinitionParser() {
   protected CollectionType collectionType() {
    return CollectionType.LIST;
   }
  });
  registerBeanDefinitionParser(”set“, new CollectionBeanDefinitionParser() {
   protected CollectionType collectionType() {
    return CollectionType.SET;
   }
  });

  这里主要看一下关于reference的内容,list、set基本的思路与reference基本一致,其实就是reference的复数(集合)形式。

  首先可以看到负责解释reference的是ReferenceBeanDefinitionParser,这个类的精简之后的代码如下:
class ReferenceBeanDefinitionParser extends AbstractReferenceDefinitionParser {
protected Class getBeanClass(Element element) {
  return OsgiServiceProxyFactoryBean.class;
}
}

  从这里基本可以看出,一个reference元素被解析之后,将产生一个关于OsgiServiceProxyFactoryBean的BeanDefinition,xml元素携带的信息由这个FactoryBean接受并负责在运行创建合适的service对象代理。下面来看看这个FactoryBean中最主要的一个方法的代码:

Object createProxy() {

// 关于调用时线程上下文ClassLoader的拦截器。
// osgi规范没有定义在导出的service被调用时的线程上下文ClassLoader,spring-dm通过环绕拦截器的方式增加了这一控制点。在xml配置中可以指定unmanaged、service-provider。
  final ServiceProviderTCCLInterceptor tcclAdvice = new ServiceProviderTCCLInterceptor();
// 监听器,实时获得当前被选中的service,从而实时更新当前的service-provider,设置正确的ClassLoader。说白了就是提供正确的ClassLoader给上面的拦截器。
  final OsgiServiceLifecycleListener tcclListener = tcclAdvice.new ServiceProviderTCCLListener();
// 从变量的命名可以看出lookupAdvice,非常可能是在确定当前符合各项过滤限制的service对象,
实际上确实是这样,但是由于osgi的动态性,对于service的管理还是有一定复杂度的。
  final ServiceDynamicInterceptor lookupAdvice = new ServiceDynamicInterceptor(getBundleContext(),
   getUnifiedFilter(), getAopClassLoader());
// 设置service的依赖策略
  lookupAdvice.setRequiredAtStartup(getCardinality().isMandatory());
// 这里可以看到在lookupAdvice被赋予了两部分的监听器。第一部分是getListeners()提供的,这一部分是由reference的子元素listener定义的。第二部分是tcclListener,这一个就是刚刚看到的那个ClassLoader的监听器了。
  OsgiServiceLifecycleListener[] listeners = addListener(getListeners(), tcclListener);

  lookupAdvice.setListeners(listeners);
  synchronized (monitor) {
   lookupAdvice.setRetryParams(retriesNumber, retryTimeout);
   retryTemplate = lookupAdvice.getRetryTemplate();
  }
  lookupAdvice.setApplicationEventPublisher(applicationEventPublisher);

  lookupAdvice.setStateListeners(stateListeners);
  lookupAdvice.setServiceImporter(this);

// 定制一个ServiceProxyCreator,这里主要是定制createDispatcherInterceptor,createServiceProviderTCCLAdvice
  ServiceProxyCreator creator = new AbstractServiceProxyCreator(getInterfaces(), getAopClassLoader(),
   getBeanClassLoader(), getBundleContext(), getContextClassLoader()) {
   ServiceInvoker createDispatcherInterceptor(ServiceReference reference) {
    // 由lookupAdvice充当ServiceInvoker
    return lookupAdvice;
   }
   Advice createServiceProviderTCCLAdvice(ServiceReference reference) {
    return tcclAdvice;
   }
  };

// 通过ServiceProxyCreator创建一个service的代理对象,处理对于这个service的方法调用。
  ProxyPlusCallback proxyPlusCallback = creator.createServiceProxy(lookupAdvice.getServiceReference());

  synchronized (monitor) {
   proxy = proxyPlusCallback.proxy;
   destructionCallback = new DisposableBeanRunnableAdapter(proxyPlusCallback.destructionCallback);
  }

  lookupAdvice.setProxy(proxy);

  lookupAdvice.afterPropertiesSet();

  return proxy;
}

  createServiceProxy方法大致的思路就是利用spring-aop的ProxyFactory结合一系列相关的advice创建出合适的proxy。到这儿,粗略的处理过程就是这样,但是好像几乎没有看到同osgi相关的什么东西,这里我们忽略了一个十分重要的对象ServiceDynamicInterceptor,正是这个拦截器它处理了service的定位。

  ServiceDynamicInterceptor继承了ServiceInvoker,先看看ServiceInvoker的代码:
protected Object doInvoke(Object service, MethodInvocation invocation) throws Throwable {
  Method method = invocation.getMethod();
  try {
   return method.invoke(service, invocation.getArguments());
  }
  catch (IllegalAccessException ex) {
   throw (RuntimeException) new IllegalAccessException(….)
  }
  catch (InvocationTargetException ex) {
   throw ex.getTargetException();
  }
}
public final Object invoke(MethodInvocation invocation) throws Throwable {
  return doInvoke(getTarget(), invocation);
}

  不难得到getTarget这个方法的实现应该是这个体系中关键的一环,再继续查看在ServiceDynamicInterceptor中getTarget的实现,可以看到它是依赖于private ServiceWrapper wrapper这样一个字段的。在代码中查找对wrapper的操作,很多重要的操作都是由一个名为Listener的ServiceDynamicInterceptor的内部类发起的,而这个内部类唯一的实例在afterPropertiesSet方法中被引用了,OsgiListenerUtils.addSingleServiceListener(bundleContext, listener, filter)。至此终于看到同osgi关联比较紧密的地方了,这是一个监听osgi中关于service状态变更的重要入口。Listener中的serviceChanged方法主要是针对service的注册、修改、卸载做了相应的回调处理,并依据当前已经存在的ServiceReference做必要的更新。当然在卸载的时候会重新启动原始的基于osgi的service查找,newReference = OsgiServiceReferenceUtils.getServiceReference(bundleContext, (filter == null ? null : filter.toString())),其中spring-dm会依据ranking(越大越好)、serviceId(越小越好)的原则过滤出至多一个ServiceReference,然后模拟service修改的方式再次调用serviceChanged方法来处理剩下的问题。最后在适当的地方播发service的bind、unbind事件(tcclListener 等)。如果在调用getTarget方法时不能确定service引用,则表示当前没有任何时候的对象被发布到osgi的运行环境中,这个时候会触发ServiceUnavailableException的抛出。

  总的来看,spring-dm对osgi中service的引入是基于aop技术的,通过一个代理对象向外提供一个稳定的统一的引用(占位符),同时通过不同的advice实现它不同的附加功能,最重要的lookupAdvice使用osgi框架的ServiceListener监听相关service的动态更动,从而实时更新目标service(其实是对wrapper对象的实时维护)。从动态性上面来看lookupAdvice有点类似于spring-aop中的TargetSource。
PS:以上代码阅读基于spring-osgi-1.1.2
分享到:
评论

相关推荐

    spring-dm-osgi整合jar包

    2. Spring DM库:如`spring-osgi-core`, `spring-osgi-io`, `spring-osgi-extender`等,提供了与OSGi环境交互的接口和工具。 3. OSGi框架库:如`org.eclipse.osgi`,这是实现OSGi规范的实现,例如Equinox或Felix。 4...

    SpringDM笔记28-Spring And OSGi:Layers of Integration

    标题中的"SpringDM笔记28-Spring And OSGi:Layers of Integration"表明这是一篇关于Spring框架与OSGi(Open Service Gateway Initiative)集成的详细笔记。OSGi是一种模块化系统,它允许Java应用程序以模块化的方式...

    spring-boot-with-embeded-osgi:带有嵌入式OSGI框架的Spring Boot项目

    带有嵌入式OSGI的Spring Boot 这是一个嵌入了Felix OSGI框架的示例Spring Boot项目。 其他项目是API(接口和模型类)及其实现。 Spring Boot应用程序将这些程序包作为OSGI框架的额外程序包公开(以便能够使用公开的...

    spring-dm.jar

    **三、spring-osgi-1.2.1-with-dependencies** 这个压缩包包含了spring-dm的1.2.1版本以及其依赖的库文件。在使用前,需要将其解压,并将包含的JAR文件添加到你的OSGi容器(如 Felix、Equinox 等)的类路径中。这样...

    spring-DM 分布式

    【Spring-DM 分布式】是一种基于Spring Dynamic Modules (Spring-DM)的分布式服务框架,旨在简化在OSGi(Open Service Gateway Initiative)环境下构建分布式应用的过程。Spring-DM是Spring框架与OSGi服务的结合,它...

    spring osgi 入门

    Spring Dynamic Modules (Spring DM) 是Spring Framework的一个扩展项目,它使得Spring可以在OSGi环境中运行,进而为开发者提供了模块化的应用程序开发能力。通过将Spring与OSGi相结合,开发者能够享受到以下优势: ...

    spring-osgi-1.2.1-with-dependencies.zip

    spring-osgi-1.2.1-with-dependencies.zip spring-osgi-1.2.1-with-dependencies.zip spring-osgi-1.2.1-with-dependencies.zip

    spring-dm-reference

    Spring DM 主要用于简化在 OSGi 平台上开发 Spring 应用程序的过程,并提供了许多高级功能来支持动态模块化应用。 ##### 为什么选择 Spring Dynamic Modules? 1. **集成性**: Spring DM 提供了一个强大的集成平台...

    spring-osgi-1.2.0-rc1-with-dependencies.zip

    "spring-osgi-1.2.0-rc1"是Spring OSGi的一个早期版本,"RC1"代表Release Candidate 1,意味着这是正式发布前的最后一个测试版本。在这个版本中,开发者可以期待一些新特性和改进,但同时也可能存在一些未发现的...

    spring-dm对应的demo

    3. **spring-osgi-*.jar**:这是Spring DM的核心库和扩展器,用于在OSGI环境中管理和扩展Spring应用。 4. **logback*.jar**:Logback是一个日志框架,用于记录应用程序的日志信息。 通过这个demo,你可以学习到如何...

    SpringDM笔记7-开发SpringDM Bundle

    **SpringDM笔记7-开发SpringDM Bundle** SpringDM(Spring Dynamic Modules)是Spring框架的一个扩展,专门用于OSGi(Open Service Gateway Initiative)环境中的应用程序开发。OSGi是一种Java模块化系统,它允许...

    SpringDM笔记31-Testing with OSGi and SpringDM

    标题 "SpringDM笔记31-Testing with OSGi and SpringDM" 涉及到的是在OSGi环境中使用SpringDM进行测试的相关知识。OSGi(Open Service Gateway Initiative)是一种Java模块化系统,允许动态地发现、加载和卸载服务。...

    spring-osgi-1.2.1-with-dependencies

    总结来说,“spring-osgi-1.2.1-with-dependencies”是一个集成了Spring与OSGi的完整包,它提供了在OSGi环境中运行Spring应用所需的所有组件和服务。通过理解和掌握这个包,开发者可以更好地利用OSGi的模块化优势,...

    Pro Spring Dynamic Modules for OSGi Service Platforms

    ### Spring-DM框架与OSGi服务平台整合应用详解 #### 一、Spring-DM框架概述 Spring-DM(Dynamic Modules)框架是Spring框架的一个扩展,它主要为在OSGi环境中运行Spring应用程序提供支持。该框架使得开发人员能够...

    spring-dm_springboot管理后台模板_spring-dm_seen1bc_bootstrap框架_box5v4_

    Spring DM使得在OSGi容器中部署和管理Spring应用变得容易,但现代Spring Boot项目通常不再需要Spring DM,因为Spring Boot已经提供了足够的功能来处理服务的生命周期和依赖管理。 Bootstrap是Twitter开源的一款前端...

    spring-osgi-1.2.0-with-dependencies.zip

    spring-osgi-1.2.0-with-dependencies.zip spring-osgi-1.2.0-with-dependencies.zip spring-osgi-1.2.0-with-dependencies.zip

    未来10年:OSGi、Spring-DM.docx

    未来10年:OSGi、Spring-DM OSGi(Open Service Gateway Initiative)是一种基于Java的动态模块化框架,旨在解决Java EE开发及部署模型的局限性。该框架可以提供模块化、动态性和灵活性,解决研发、部署和维护等...

    osgi-SpringDM

    Spring-DM指的是 Spring ...Spring-DM 的主要目的是能够方便地将 Spring 框架和OSGi框架结合在一起,使得使用Spring的应用程序可以方便简单地部署在OSGi环境中,利用OSGi框架提供的服务,将应用变得 更加模块化。

    spring-osgi-1.2.1.rar

    - Spring OSGi早期版本使用Spring DM(Dependency Manager),它是Spring OSGi的核心组件,负责管理bundle间的依赖和服务。 - Spring DM通过读取Spring配置来管理OSGi服务,使得开发者可以使用熟悉的Spring XML...

Global site tag (gtag.js) - Google Analytics