在osgi bundle中访问osgi container之外的传统服务

      osgi container是java实践中的一个框架,在这个框架中,按照osgi的规范,实现了java中module的思想,从而真正实现了java的模块化开发。

      在模块的互用方面,osgi提供了两种方式:一是通过export/import包实现,二是通过在osgi bundlecontext中注册service,实现各个模块之间的交互。第二种方式符合SOA的标准,是osgi中推荐的交互方式。同样的,osgi container和传统的java 进程交互,也提供了同样的方式,在《在osgi容器外应用osgi bundle提供的服务》一文中,分析了如何在osgi container外部,引用osgi服务的一种方式,同样的在osgi bundle中引用传统java进行的服务,也是通过osgi container的bundleContext实现的。

     下面是实现在osgi bundle中访问一个外部的service的完整的过程。

      一、在osgi container中注册一个外部的服务(这个例子实在Apache的felix container中完成)

      在felix的host对象中,首先实例化一个felix对象,然后,初始化felix,随后在felix container的bundlecontext中注册一个服务

            m_felix = new Felix(config);
            m_felix.init();
            AutoProcessor.process(config, m_felix.getBundleContext());
            m_felix.getBundleContext().registerService(ShareInterface.class.getName(), new ShareImpl(), null);
          // Now start Felix instance.
            m_felix.start();

 

 二、在bundle中引用这个注册的服务

      虽然这个服务已经注册到osgi container的bundlecontext中了,但是在bundle中利用正常的ServiceTracker无法引用到这个服务(可能是由于注册时,不在osgi container中,所以,没有在osgi的整个环境中出现),但是,这个服务在system bundle中是可见的,所以,可以通过访问system bundle的bundlecontext来获得这个外部的服务

		Bundle[] bundles = context.getBundles();

		ServiceTracker st = new ServiceTracker(bundles[0].getBundleContext(),ShareInterface.class.getName(),null);
		st.open();
		Object si =  st.getService();
		Method m = si.getClass().getDeclaredMethod("share", null);
		m.invoke(si, null);

 同样的,由于服务注册时,不在osgi container的环境中,所以服务实例化的classloader和osgi container中的classloader之间不能够直接的访问,利用反射的方法,可以访问到注册的服务,就实现了osgi bundle访问osgi container之外的服务了。

 

 

你可能感兴趣的:(apache,框架,osgi,SOA)