OSGI企业应用开发(七)细说Blueprint & Gemini Blueprint(二)
上篇文章介绍了标准的Blueprint 规范与 Gemini Blueprint如何自定义Bean配置文件路径,本文接着上篇文章继续介绍Blueprint的使用。
一、Bean的配置
前面提到过,Gemini Blueprint即实现了Blueprint 规范,又兼容Spring DM风格的配置,本节我们再来了解一下Blueprint与Spring DM在Bean的配置上的差异,具体如下表所示:
(注意:这两种风格Gemini Blueprint都支持。)
如上图所示,Spring DM风格的Bean配置和Blueprint还是有一些差异的,首先体现在根元素和命名空间声明上,Spring DM根元素为<beans>
,命名空间声明如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true">
</beans>
而Blueprint根元素为<blueprint>
,命名空间声明如下:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
</blueprint>
相比之下,Blueprint的配置要稍微简单些,除了根元素和命名空间声明外,Bean的配置的主要差异如下:
1、Spring DM使用根元素的default-lazy-init属性指定IoC容器启动时是否立刻实例化所有的Bean,而Blueprint对应的属性为default-activation。
2、Spring DM可以通过default-init-method和default-destroy-method属性指定Bean实例化和销毁时默认的回调方法,还可以通过default-autowire, default-autowire-candidates属性指定Bean的自动装配策略,而这些属性Blueprint是不支持的。
3、Spring DM的Bean支持使用name属性,还支持使用alias属性为Bean指定一个别名,Blueprint是不支持的。
4、Spring DM 配置Bean的scope属性支持singleton, prototype, request, session, bundle等取值,而Blueprint Bean的scope属性仅仅支持singleton, prototype。
5、Spring DM通过Bean的lazy-init属性指定IoC容器启动时是否实例化该Bean,Blueprint对应的属性为activation。
6、Spring DM通过factory-bean属性指定工厂Bean,而Blueprint对应的属性为factory-ref。
7、Spring DM可以使用parent属性继承一个Bean的配置,而Blueprint不支持。
8、Spring DM 通过autowire, autowire-candidate属性指定Bean的自动装配策略,而Blueprint也是不支持的。
9、构造器注入时,Spring DM使用的标签为<constructor-arg>
,而Blueprint使用的标签为<argument>
。
Spring DM 和 Blueprint 风格的Bean的配置差异主要体现在上面几个方面,接下来我们开始学习Bean的注册与引用。
二、Bundle中Bean的注册与引用
前面的文章中有提到过,OSGI应用的每一个Bundle都是使用不同的类加载器加载,OSGI应用并不像普通的Java应用一样,有全局的Classpath的概念,所以如果需要在一个Bundle中使用另外一个Bundle中的类,则需要另外一个Bundle导出这些类,然后在用到这些类的Bundle中导入即可。而OSGI应用对象的共享则是通过服务注册的方式实现。
使用Blueprint將Spring框架整合到OSGI中,ApplicationContext和普通的Java应用也有所差异。一般来说,普通Java应用的ApplicationContext只有一个,而且是全局的,而在OSGI应用中,每个Bundle对应一个单独个ApplicationContext,如下图所示:
从上图可以清晰的看出,每个Bundle对应的ApplicationContext是不同的,也就是说每个Bundle中配置的Bean是不共享的,例如当我们在A Bundle中定义了一个Bean,然后以属性注入的方式注入到B Bundle中的一个Bean中,这就有问题了,那么如何解决这个问题呢,Spring DM给出的解决方案是將Bean注册为服务,然后在其他Bundle中引用Bean。接下来我们就来学习一下Bean的注册与引用机制。
Spring DM Bean的注册与引用机制实际上有个缺点,它要求被注册的Bean必须实现了某个接口,为了方便说明问题,笔者在前面文章中搭建好的环境中进行演示,首先我们可以在com.csdn.osgi.common工程中新建一个com.csdn.osgi.domain.Employee接口,表示员工的信息,内容如下:
package com.csdn.osgi.domain;
public interface Employee {
public String getName();
public int getAge();
public String getAddress();
}
然后定义一个具体的类来实现Employee 接口,比如我们有实现类com.csdn.osgi.domain.Programmer,如下:
package com.csdn.osgi.domain;
public class Programmer implements Employee{
private String name; // 员工姓名
private int age; // 员工年龄
private String address; // 居住地址
private double salary; // 员工薪资
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
接着在com.csdn.osgi.common工程中,新建 META-INF/spring/employee.xml文件,在新建的文件中,配置一个Programmer类的实例,如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="false">
<bean id="programmer" class="com.csdn.osgi.domain.Programmer">
<property name="name" value="Smith"/>
<property name="age" value="25"/>
<property name="address" value="Nanjin"/>
<property name="salary" value="2000"/>
</bean>
</beans>
如上面代码所示,我们在com.csdn.osgi.common这个Bundle中通过Spring实例化了一个Programmer对象,其他Bundle中如果需要注入这个实例,该怎样做呢?
接下来我们在com.csdn.osgi.helloworld工程中,新建一个Company类,表示公司信息,例如:
package com.csdn.osgi.domain;
public class Company {
private String name; // 公司名称
private Employee emp; // 假设只有一个员工
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee getEmp() {
return emp;
}
public void setEmp(Employee emp) {
this.emp = emp;
}
}
项目结构如下图所示:
需要注意的是,Company类在com.csdn.osgi.helloworld这个Bundle中,而Programmer类在com.csdn.osgi.common中,我们需要在com.csdn.osgi.common这个Bundle中导出com.csdn.osgi.domain这个包,具体做法很简单,可以將com.csdn.osgi.common工程中的MANIFEST.MF文件,修改成如下内容:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Common
Bundle-SymbolicName: com.csdn.osgi.common
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.csdn.osgi.common.Activator
Bundle-Vendor: CSDN
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.csdn.osgi.domain
其中Export-Package: com.csdn.osgi.domain
为新增内容,解决依赖问题后,我们可以在com.csdn.osgi.helloworld工程中,新建一个config/company.xml文件(注意:前面我们通过Spring-Context头自定义了Bean配置文件路径为config/*.xml),然后配置一个Company实例,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="false">
<bean id="company" class="com.csdn.osgi.domain.Company">
<property name="name" value="CSDN"/>
<property name="emp" ref="programmer"/>
</bean>
</beans>
这里我们直接將com.csdn.osgi.common Bundle中配置的employee对象注入,然后启动OSGI容器,看看会有什么问题,控制台输出日志如下:
十二月 25, 2016 9:08:05 下午 org.eclipse.gemini.blueprint.extender.internal.boot.ChainActivator <init>
信息: Blueprint API detected; enabling Blueprint Container functionality
十二月 25, 2016 9:08:05 下午 org.eclipse.gemini.blueprint.extender.internal.activator.LoggingActivator start
信息: Starting [org.eclipse.gemini.blueprint.extender] bundle v.[2.0.0.M02]
osgi> 十二月 25, 2016 9:08:05 下午 org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration start
信息: No custom extender configuration detected; using defaults...
十二月 25, 2016 9:08:05 下午 org.springframework.scheduling.timer.TimerTaskExecutor afterPropertiesSet
信息: Initializing Timer
hello world!
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator createApplicationContext
信息: Discovered configurations {osgibundle:/META-INF/spring/*.xml} in bundle [Common (com.csdn.osgi.common)]
Hello World!!
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator createApplicationContext
信息: Discovered configurations {config/*.xml} in bundle [Helloworld (com.csdn.osgi.helloworld)]
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintContainerCreator createApplicationContext
信息: Discovered configurations {bundleentry://43.fwk1878169648/OSGI-INF/blueprint/beans.xml} in bundle [Helloworld (com.csdn.osgi.helloworld)]
十二月 25, 2016 9:08:06 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.common, config=osgibundle:/META-INF/spring/*.xml): startup date [Sun Dec 25 21:08:06 CST 2016]; root of context hierarchy
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 25, 2016 9:08:06 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=config/*.xml): startup date [Sun Dec 25 21:08:06 CST 2016]; root of context hierarchy
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 25, 2016 9:08:06 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=bundleentry://43.fwk1878169648/OSGI-INF/blueprint/beans.xml): startup date [Sun Dec 25 21:08:06 CST 2016]; root of context hierarchy
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from OSGi resource[bundleentry://43.fwk1878169648/OSGI-INF/blueprint/beans.xml|bnd.id=43|bnd.sym=com.csdn.osgi.helloworld]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://43.fwk1878169648/config/beans.xml]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://37.fwk1878169648/META-INF/spring/beans.xml]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://43.fwk1878169648/config/company.xml]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://37.fwk1878169648/META-INF/spring/dmconfig.xml]
十二月 25, 2016 9:08:06 下午 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://43.fwk1878169648/OSGI-INF/blueprint/beans.xml)
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://43.fwk1878169648/config/dmconfig.xml]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://37.fwk1878169648/META-INF/spring/employee.xml]
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@48766948: defining beans [helloWorld,blueprintBundle,blueprintBundleContext,blueprintContainer,blueprintConverter]; root of factory hierarchy
================Hello World================
十二月 25, 2016 9:08:06 下午 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=config/*.xml)
十二月 25, 2016 9:08:06 下午 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)
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6ec2b45d: defining beans [object,length,buffer,current-time,list,programmer]; root of factory hierarchy
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@30a0eb63: defining beans [helloWorld1,helloWorld2,company]; root of factory hierarchy
================Hello World================
================Hello World================
=========Company=========
十二月 25, 2016 9:08:06 下午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@30a0eb63: defining beans [helloWorld1,helloWorld2,company]; root of factory hierarchy
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.internal.support.DefaultOsgiBundleApplicationContextListener onOsgiApplicationEvent
严重: Application context refresh failed (OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=config/*.xml))
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'company' defined in URL [bundleentry://43.fwk1878169648/config/company.xml]: Cannot resolve reference to bean 'programmer' while setting bean property 'emp'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'programmer' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:60)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:325)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:290)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'programmer' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1041)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 17 more
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.context.support.AbstractOsgiBundleApplicationContext unpublishContextAsOsgiService
信息: Application Context service already unpublished
十二月 25, 2016 9:08:06 下午 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}
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.internal.support.DefaultOsgiBundleApplicationContextListener onOsgiApplicationEvent
信息: Application context succesfully closed (OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=config/*.xml))
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor fail
严重: Unable to create application context for [com.csdn.osgi.helloworld], unsatisfied dependencies: none
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'company' defined in URL [bundleentry://43.fwk1878169648/config/company.xml]: Cannot resolve reference to bean 'programmer' while setting bean property 'emp'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'programmer' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:60)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:325)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:290)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'programmer' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1041)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 17 more
十二月 25, 2016 9:08:06 下午 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}
十二月 25, 2016 9:08:06 下午 org.eclipse.gemini.blueprint.extender.internal.support.DefaultOsgiBundleApplicationContextListener onOsgiApplicationEvent
信息: Application context successfully refreshed (OsgiBundleXmlApplicationContext(bundle=com.csdn.osgi.helloworld, config=bundleentry://43.fwk1878169648/OSGI-INF/blueprint/beans.xml))
十二月 25, 2016 9:08:06 下午 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}
十二月 25, 2016 9:08:06 下午 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))
错误信息意思很明显,名称为programmer这个Bean未定义,原因是该Bean定义在com.csdn.osgi.common这个Bundle中,在com.csdn.osgi.helloworld Bundle中无法直接访问,接下来我们通过Bean的注册和引用来解决该问题。
在com.csdn.osgi.common工程中,新建一个META-INF/spring/dmconfig.xml文件,用来注册Bean,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint
http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd">
<osgi:service id="employee" ref="programmer" interface="com.csdn.osgi.domain.Employee" />
</beans>
然后在com.csdn.osgi.helloworld Bundle中,新建config/dmconfig.xml文件,我们在该文件中引入其他Bundle中注册的Bean,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint
http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd">
<osgi:reference id="employee" interface="com.csdn.osgi.domain.Employee" />
<alias name="employee" alias="programmer"/>
</beans>
需要注意的是,<osgi:service/>
标签的id属性值不能和Bean的id相同。上面的配置中我们使用<alias/>
标签为employee指定别名为programmer,然后重启OSGI容器,会发现com.csdn.osgi.common Bundle中定义的名称为programmer的Bean成功注入到Company类中。
Bean的注册与引用机制对项目开发非常重要,在后面整合Mybatis时,我们可以將用于操作数据库的SqlSessionTemplate注册为服务,然后在其他Bundle就可以引用该服务操作数据库了。
OSGI企业应用开发(七)细说Blueprint & Gemini Blueprint(二)的更多相关文章
- OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
上篇文章中介绍了如何使用独立的Equinox发行包搭建OSGI运行环境,而不是依赖与具体的Eclipse基础开发工具,本文开始介绍如何使用Blueprint將Spring框架整合到OSGI中. 一.开 ...
- OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)
上篇文章中,我们开发了一个自定义的Bundle,接着从网络中下载到Spring和Blueprint的Bundle,然后复制到DynamicRuntime项目下. 需要注意的是,这些Bundle并不能在 ...
- OSGI企业应用开发(八)整合Spring和Mybatis框架(一)
到目前为止,我们已经学习了如何使用Blueprint將Spring框架整合到OSGI应用中,并学习了Blueprint&Gemini Blueprint的一些使用细节.本篇文章开始,我们將My ...
- OSGI企业应用开发(六)细说Blueprint & Gemini Blueprint(一)
上篇文章介绍了如何使用Blueprint將Spring框架整合到OSGI应用的Bundle中,从上篇文章中我们大概了解了Blueprint与Gemini Blueprint的关系,简单的说,Bluep ...
- OSGI企业应用开发(十四)整合Spring、Mybatis、Spring MVC
作为一个企业级的Web应用,MVC框架是必不可少的.Spring MVC目前使用也比较广泛,本文就来介绍一下如何在OSGI应用中实现Spring.Mybatis.Spring MVC框架的整合,其中S ...
- OSGI企业应用开发(十)整合Spring和Mybatis框架(三)
上篇文章中,我们已经完成了OSGI应用中Spring和Mybatis框架的整合,本文就来介绍一下,如何在其他Bundle中,使用Mybatis框架来操作数据库. 为了方便演示,我们新建一个新的Plug ...
- OSGI企业应用开发(九)整合Spring和Mybatis框架(二)
上篇文章中,我们完成了在OSGI应用中整合Spring和Mybatis框架的准备工作,本节我们继续Spring和Mybatis框架的整合. 一.解决OSGI整合Spring中的Placeholder问 ...
- OSGI企业应用开发(三)Eclipse中搭建Equinox运行环境
上篇文章介绍了如何在Eclipse中搭建Felix的运行环境,我们需要將Bundle发布到Felix框架的bundle目录下,Felix框架启动时才会自动加载这些Bundle,否则需要在Felix框架 ...
- OSGI企业应用开发(十三)OSGI Web应用开发(二)
上篇文章介绍了OSGI Web应用的两种开发模式,并把Jetty应用服务器以Bundle的形式整合到Equinox容器中,已这种模式开发Web应用,所有的应用程序资源,例如Servlet.JSP.HT ...
随机推荐
- POJ 2583
#include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...
- 【Canal源码分析】数据传输协议
Canal的数据传输有两块,一块是进行binlog订阅时,binlog转换为我们所定义的Message,第二块是client与server进行TCP交互时,传输的TCP协议. 一.EntryProto ...
- JavaScript -- Select
-----053-Select.html----- <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- wnmp(windows+nginx+mysql+php)环境搭建和配置
要求 必备知识 熟悉基本编程环境搭建. 运行环境 windows 7(64位); nginx-1.4.7;MySQL Server 5.5php-5.4.39-nts 下载地址 环境下载 Nginx是 ...
- Linux 各种运算符
目录 - 算术运算符 - 关系运算符 - 逻辑运算符 - 按位运算符 - 文件测试符 - 算术运算符 算术运算符,常用的有+.-.*./.%.++.--.** + - 加法运算符 [root@www ...
- gcc编译时对’xxxx’未定义的引用问题
gcc编译时对’xxxx’未定义的引用问题 原因 解决办法 gcc 依赖顺序问题 在使用gcc编译的时候有时候会碰到这样的问题,编译为.o(obj) 文件没有问题,但是编译(这一步应该是链接)为可执行 ...
- 如何做实时监控?—— 参考 Spring Boot 实现(转)
转自:http://blog.csdn.net/xiaoyu411502/article/details/48129057 随着 微服务 的流行,相比较以前一个大型应用程序搞定所有需求,我们现在更倾向 ...
- CustomSqlSessionFactoryBean
import java.io.File; import java.net.JarURLConnection; import java.net.URL; import java.util.ArrayLi ...
- 疯狂Java讲义PDF
java学习资料,仅供学习交流,自行取用↓ 链接:https://pan.baidu.com/s/1dF1wCST 密码:i75g
- Git学习笔记4
现在,远程库已经准备好了,下一步是用命令git clone克隆一个本地库: $ git clone git@github.com:michaelliao/gitskills.git 要克隆一个仓库,首 ...