上篇文章介绍了如何使用Blueprint將Spring框架整合到OSGI应用的Bundle中,从上篇文章中我们大概了解了Blueprint与Gemini Blueprint的关系,简单的说,Blueprint是OSGI Alliance借鉴了Spring Dynamic Modules 的思想,为OSGI制定的依赖注入(DI)规范,而Gemini Blueprint的前生是Spring DM,它即兼容之前的Spring DM,又实现了Blueprint规范。本篇文章开始,我们就来了解一下Gemini Blueprint的一些重要使用细节,以及它与Blueprint的差异。

一、自定义Bean配置文件路径

上篇文章中,我们知道,使用Blueprint整合Spring后,默认情况下,Gemini Blueprint会从Bundle的META-INF/spring目录下读取Bean的配置文件,而实际上标准的Blueprint规范会从OSGI-INF/blueprint目录下加载Bean的配置文件,为了说明这个观点,我们不妨在篇文章的代码基础上新建一个Bundle来演示。

首先新建一个Plug-in Project,名称为com.csdn.osgi.helloworld,步骤和前面文章中相同,如果读者不知道如何操作,可以阅读本系列博文的前面几篇,完成后工程如下图所示:



前面提到过,Gemini Blueprint支持标准的Blueprint规范,所以我们把Bean的配置文件放到OSGI-INF/blueprint目录下也是可以的,为了方便观察Bean是否被实例化,我们可以新建一个Java类,com.csdn.osgi.HelloWorld,内容如下:

package com.csdn.osgi;

public class HelloWorld {

    public HelloWorld() {
System.out.println("================Hello World================");
}
}

如上面代码所示,我们可以在HelloWorld类的构造方法中,输出一些日志信息,这样实例化HelloWorld对象时,控制台中就会打印相应的信息。

接下来在com.csdn.osgi.helloworld工程中,新建OSGI-INF/blueprint目录,在该目录下新建Bean的配置文件beans.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="helloWorld" class="com.csdn.osgi.HelloWorld"/> </blueprint>

最后,启动Equinox容器,注意要勾选我们新建的Bundle,名称为com.csdn.osgi.helloworld,如下图所示:



启动后,控制台输出日志内容如下:

hello world!
十二月 22, 2016 9:44:16 下午 org.eclipse.gemini.blueprint.extender.internal.boot.ChainActivator <init>
信息: Blueprint API detected; enabling Blueprint Container functionality
十二月 22, 2016 9:44:16 下午 org.eclipse.gemini.blueprint.extender.internal.activator.LoggingActivator start
信息: Starting [org.eclipse.gemini.blueprint.extender] bundle v.[2.0.0.M02]
osgi> 十二月 22, 2016 9:44:16 下午 org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration start
信息: No custom extender configuration detected; using defaults...
十二月 22, 2016 9:44:16 下午 org.springframework.scheduling.timer.TimerTaskExecutor afterPropertiesSet
信息: Initializing Timer
十二月 22, 2016 9:44:16 下午 org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator createApplicationContext
信息: Discovered configurations {osgibundle:/META-INF/spring/*.xml} in bundle [Common (com.csdn.osgi.common)]
十二月 22, 2016 9:44:17 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.common, config=osgibundle:/META-INF/spring/*.xml): startup date [Thu Dec 22 21:44:17 CST 2016]; root of context hierarchy
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 22, 2016 9:44:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://9.fwk1970436060/META-INF/spring/beans.xml]
Hello World!!
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintContainerCreator createApplicationContext
信息: Discovered configurations {bundleentry://35.fwk1970436060/OSGI-INF/blueprint/beans.xml} in bundle [Helloworld (com.csdn.osgi.helloworld)]
十二月 22, 2016 9:44:17 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=bundleentry://35.fwk1970436060/OSGI-INF/blueprint/beans.xml): startup date [Thu Dec 22 21:44:17 CST 2016]; root of context hierarchy
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 22, 2016 9:44:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from OSGi resource[bundleentry://35.fwk1970436060/OSGI-INF/blueprint/beans.xml|bnd.id=35|bnd.sym=com.csdn.osgi.helloworld]
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor stageOne
信息: No outstanding OSGi service dependencies, completing initialization for OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.common, config=osgibundle:/META-INF/spring/*.xml)
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor stageOne
信息: No outstanding OSGi service dependencies, completing initialization for OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=bundleentry://35.fwk1970436060/OSGI-INF/blueprint/beans.xml)
十二月 22, 2016 9:44:17 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@24259add: defining beans [helloWorld,blueprintBundle,blueprintBundleContext,blueprintContainer,blueprintConverter]; root of factory hierarchy
十二月 22, 2016 9:44:17 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2b8730e8: defining beans [object,length,buffer,current-time,list]; root of factory hierarchy
================Hello World================
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.blueprint.container.support.BlueprintContainerServicePublisher registerService
信息: Publishing BlueprintContainer as OSGi service with properties {Bundle-SymbolicName=com.csdn.osgi.helloworld, Bundle-Version=1.0.0.qualifier, osgi.blueprint.container.version=1.0.0.qualifier, osgi.blueprint.container.symbolicname=com.csdn.osgi.helloworld}
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext publishContextAsOsgiServiceIfNecessary
信息: Publishing application context as OSGi service with properties {org.eclipse.gemini.blueprint.context.service.name=com.csdn.osgi.helloworld, org.springframework.context.service.name=com.csdn.osgi.helloworld, Bundle-SymbolicName=com.csdn.osgi.helloworld, Bundle-Version=1.0.0.qualifier}
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext publishContextAsOsgiServiceIfNecessary
信息: Publishing application context as OSGi service with properties {org.eclipse.gemini.blueprint.context.service.name=com.csdn.osgi.common, org.springframework.context.service.name=com.csdn.osgi.common, Bundle-SymbolicName=com.csdn.osgi.common, Bundle-Version=1.0.0.qualifier}
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.extender.internal.support.DefaultOsgiBundleApplicationContextListener onOsgiApplicationEvent
信息: Application context successfully refreshed (OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.common, config=osgibundle:/META-INF/spring/*.xml))
十二月 22, 2016 9:44:17 下午 org.eclipse.gemini.blueprint.extender.internal.support.DefaultOsgiBundleApplicationContextListener onOsgiApplicationEvent
信息: Application context successfully refreshed (OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=bundleentry://35.fwk1970436060/OSGI-INF/blueprint/beans.xml))

日志中输出了================Hello World================,说明我们在OSGI-INF/blueprint目录下配置的bean也能够成功被实例化。

接下来是本节的重点内容,Gemini Blueprint除了支持从默认的目录加载Bean的配置文件,还支持自定义配置文件的路径,同样支持Spring DM风格和Blueprint风格,首先介绍Spring DM风格。

有些OSGI基础的朋友应该都知道,OSGI的Bundle与普通Jar包的区别,从文件结构上来说,仅在于META-INF/MANIFEST.MF文件中的描述信息,例如我们新建的com.csdn.osgi.helloworld工程,MANIFEST.MF文件内容如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworld
Bundle-SymbolicName: com.csdn.osgi.helloworld
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.csdn.osgi.helloworld.Activator
Bundle-Vendor: CSDN
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"

MANIFEST.MF文件由多个信息头构成,具体每一项的含义这里不做过多介绍,读者可以参考OSGI规范和相关的书籍,我们可以使用Gemini Blueprint自定义的Spring-Context信息头来指定配置文件位置,使用方式如下:

Spring-Context-Value ::= context ( ',' context ) *
context ::= path ( ';' path ) * (';' directive) *

上面的表达式描述了Spring-Context的值的形式,是啥意思呢,读者可能看不懂,不要紧,看几个具体的例子就知道了,例如下面的配置方式是允许的:

Spring-Context: config/account-data-context.xml, config/account-security-context.xml

同时指定多个配置文件路径,使用逗号分割开,除此之外,还支持通配符的方式,例如:

Spring-Context: config/*.xml

上面的配置,表示加载config目录下的所有XML文件,另外,我们还可以指定一些属性,例如:

Spring-Context: config/*.xml;create-asynchronously:=false 

参数与配置文件路径使用分号分割开,create-asynchronously参数的含义是application context采用同步还是异步的方式创建,默认为异步方式,其他参数的含义读者可参考Gemini Blueprint官方文档。

接下来我们可以修改com.csdn.osgi.helloworld工程中的MANIFEST.MF文件,增加Spring-Context信息头来指定Bean的配置文件,例如:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworld
Bundle-SymbolicName: com.csdn.osgi.helloworld
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.csdn.osgi.helloworld.Activator
Bundle-Vendor: CSDN
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Spring-Context: config/*.xml

然后com.csdn.osgi.helloworld工程中新建config/beans.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="helloWorld1" class="com.csdn.osgi.HelloWorld"/>
<bean id="helloWorld2" class="com.csdn.osgi.HelloWorld"/> </blueprint>

然后重启Equinox容器,日志中输出了连续的两行信息,如下:

================Hello World================
================Hello World================

从输出日志中,可以分析出config/beans.xml中配置的Bean也能够被实例化,说明Spring-Context头指定的Bean配置文件路径生效。

需要注意的是,Spring-Context指定Bean配置文件路径是Spring DM的方式,而标准的Blueprint规范使用Bundle-Blueprint头来指定Bean配置文件路径,使用方式相同,不做过多介绍,下面是Gemini Blueprint与Blueprint自定义Bean配置文件的区别,如下图所示:

关于Blueprint与Gemini Blueprint的使用本文暂时介绍这么多,下篇文章继续。

OSGI企业应用开发(六)细说Blueprint & Gemini Blueprint(一)的更多相关文章

  1. OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)

    上篇文章中介绍了如何使用独立的Equinox发行包搭建OSGI运行环境,而不是依赖与具体的Eclipse基础开发工具,本文开始介绍如何使用Blueprint將Spring框架整合到OSGI中. 一.开 ...

  2. OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)

    上篇文章中,我们开发了一个自定义的Bundle,接着从网络中下载到Spring和Blueprint的Bundle,然后复制到DynamicRuntime项目下. 需要注意的是,这些Bundle并不能在 ...

  3. OSGI企业应用开发(八)整合Spring和Mybatis框架(一)

    到目前为止,我们已经学习了如何使用Blueprint將Spring框架整合到OSGI应用中,并学习了Blueprint&Gemini Blueprint的一些使用细节.本篇文章开始,我们將My ...

  4. OSGI企业应用开发(七)细说Blueprint & Gemini Blueprint(二)

    上篇文章介绍了标准的Blueprint 规范与 Gemini Blueprint如何自定义Bean配置文件路径,本文接着上篇文章继续介绍Blueprint的使用. 一.Bean的配置 前面提到过,Ge ...

  5. OSGI企业应用开发(十四)整合Spring、Mybatis、Spring MVC

    作为一个企业级的Web应用,MVC框架是必不可少的.Spring MVC目前使用也比较广泛,本文就来介绍一下如何在OSGI应用中实现Spring.Mybatis.Spring MVC框架的整合,其中S ...

  6. OSGI企业应用开发(十)整合Spring和Mybatis框架(三)

    上篇文章中,我们已经完成了OSGI应用中Spring和Mybatis框架的整合,本文就来介绍一下,如何在其他Bundle中,使用Mybatis框架来操作数据库. 为了方便演示,我们新建一个新的Plug ...

  7. OSGI企业应用开发(九)整合Spring和Mybatis框架(二)

    上篇文章中,我们完成了在OSGI应用中整合Spring和Mybatis框架的准备工作,本节我们继续Spring和Mybatis框架的整合. 一.解决OSGI整合Spring中的Placeholder问 ...

  8. OSGI企业应用开发(十三)OSGI Web应用开发(二)

    上篇文章介绍了OSGI Web应用的两种开发模式,并把Jetty应用服务器以Bundle的形式整合到Equinox容器中,已这种模式开发Web应用,所有的应用程序资源,例如Servlet.JSP.HT ...

  9. OSGI企业应用开发(十二)OSGI Web应用开发(一)

    前面文章中介绍了如何在OSGI应用中整合Spring和Mybatis框架,本篇文章开始介绍如何使用OSGI技术开发Web应用.对于传统的Java EE应用,应用中涉及到的Web元素无非就是Servle ...

随机推荐

  1. oracle exp imp日常使用

    http://www.cnblogs.com/ningvsban/archive/2012/12/22/2829009.html http://www.cnblogs.com/mq0036/archi ...

  2. xamarin 安卓输出中文错误 乱码解决

    在编译设置附加参数 -J-Duser.language=en 这个错误信息是来自javac 编译产生的 而中文乱码问题是 GBK 和UTF8 的问题 解决的办法就是让javac 输出英文错误信息 也可 ...

  3. webstorm引用ESLint进行静态代码检查

    安装 ESLint 基于 Node 平台,所以 Nodejs 是必须安装的,然后通过 npm 安装 ESLint 包,至于全局安装还是作为开发依赖安装,取决于个人. 然后在 WebStorm 中,打开 ...

  4. vue中修改Element ui样式不起作用

    公司做的一个后台系统,由于Elemen ui是响应式的,在小屏笔记本中,一行两列的表单会自动变成一行一列,这样就很不美观了,由于是后台系统,当时也没考虑适配问题. 老总 地表最强的电脑 运行了一下,当 ...

  5. [Python 从入门到放弃] 4. 什么是可选参数

    参数在函数中使用,顾名思义.可选参数就是:这个参数是可选的 也就是可有可无 我们来看一下这个例子: ver 1: 1.定义一个迭代输出列表元素的函数myPrint 2.参数为 列表 def myPri ...

  6. nginx 跳转系列

    1.nginx强制跳转https配置,通过http状态吗实现,http状态吗地址: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/3 ...

  7. idea调试springmvc出现java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

    idea调试springmvc出现java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderList ...

  8. KMP算法(——模板习题与总结)

    KMP算法是一种改进的模式匹配算法,相比于朴素的模式匹配算法效率更高.下面讲解KMP算法的基本思想与实现. 先来看一下朴素模式匹配算法的基本思想与实现. 朴素模式匹配算法的基本思想是匹配过程中如果该位 ...

  9. MVC应用程序显示Flash(swf)视频

    前段时间, Insus.NET有实现<MVC使用Flash来显示图片>http://www.cnblogs.com/insus/p/3598941.html 在演示中,它也可以显示Flas ...

  10. aspnetmvc和aspnetcoremvc的一些区别

    1.路由 控制器添加特性:  [RoutePrefix("api/controller")]  = >   [Route("api/[controller]&quo ...