Spring-OSGi默认加载解析META-INF/spring目录下的xml文件作为spring bean配置文件,也可通过在MANIFEST.MF中增加Spring-Context来指定spring bean配置文件。
把一个Spring bean发布为OSGi Service,只需在spring bean的xml中这么配置就行了:
<osgi:service id=”OSGi服务ID” ref=”需要发布为OSGi服务的spring bean” interface=”服务的接口”/>
要在Spring bean中引用OSGi Service,只需在spring bean的xml中这么配置:
<osgi:reference ref=”需要发布为OSGi服务的spring bean” interface=”服务接口” />
可以看出和ds中的配置基本是一致的,不过目前尚缺少对于policy这样的属性的配置,另外如要实现bind和unbind的设置,需要在osgi:reference的元素下增加osgi:listener的节点,例如:
<osgi:reference>
<osgi:listener ref=”引用了此service的spring bean”
bind-method=”服务可用时调用的方法”
unbind-method=”服务不可用时的调用的方法”/>
</osgi:reference>
这里bind-method和unbind-method的方法签名和在使用DS时稍有不同,这里bind-method和unbind-method的方法签名如下所示:
public void onBind(服务接口,Dictionary)
在上面ds的demo里把com.ferry.client bundle稍做改动,修改部分如下
增加一个类Tiny
public class Tiny implements CommandProvider{ private IAbility ability; public void setAbility(IAbility ability) { this.ability = ability; } public void onBind(IAbility ability,Map properties){ this.ability = ability; } public void onUnbind(IAbility ability,Map properties){ this.ability = null; } public void _countTinyDamage(CommandInterpreter ci){ if(ability!=null){ ci.println(ability.getName()+":"+ability.ability(4)); }else { ci.println("ability is null!"); } } @Override public String getHelp() { return "\tcountDamage - Count the damage\n"; } }
<?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.springframework.org/schema/osgi" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <bean id="tiny" class="com.ferry.hero.Tiny"> <property name="ability" ref="ability"/> </bean> <osgi:reference id="ability" interface="com.ferry.ability.IAbility"> <osgi:listener ref="tiny" bind-method="onBind" unbind-method="onUnbind"></osgi:listener> </osgi:reference> <osgi:service ref="tiny" interface="org.eclipse.osgi.framework.console.CommandProvider"> </osgi:service> </beans>
spring-dm也支持多服务提供,有list和set两种,配置如下
<osgi:list id="引用了此service的spring bean " interface="服务接口"/>
<osgi:setid="引用了此service的spring bean " interface="服务接口“/>Hero改成spring-dm 多服务提供的list方式,代码如下
public class Hero implements CommandProvider{ private List<IAbility> abilityList; public void setAbilityList(List<IAbility> abilityList) { this.abilityList = abilityList; } public void addAbility(IAbility ability) { abilityList.add(ability); System.out.println(ability.getName()); } public void removeAbility(IAbility ability) { abilityList.remove(ability); System.out.println(ability.getName()); } public void _countDamage(CommandInterpreter ci){ if (abilityList!=null&&abilityList.size()!=0) { for (IAbility ability : abilityList) { ci.println(ability.getName()+":"+ability.ability(4)); } } } @Override public String getHelp() { return "\tcountDamage - Count the damage\n"; } }
Hero对应的spring配置文件如下
<bean id="hero" class="com.ferry.hero.Hero"> <property name="abilityList" ref="abilitys"></property> </bean> <osgi:list id="abilitys" interface="com.ferry.ability.IAbility"></osgi:list> <osgi:service ref="hero" interface="org.eclipse.osgi.framework.console.CommandProvider"> </osgi:service>
代码运行结果大家可以通过我提供的代码自己运行,这里就不截图了
用到的jar包
com.springsource.org.aopalliance-1.0.0.jar
jcl-over-slf4j-1.6.4.jar
logback-classic-1.0.0.jar
logback-core-1.0.0.jar
org.eclipse.equinox.ds_1.3.1.R37x_v20110701.jar
org.eclipse.equinox.util_1.0.300.v20110502.jar
org.eclipse.osgi.services_3.3.0.v20110513.jar
org.eclipse.osgi_3.7.2.v20120110-1415.jar
org.springframework.aop-2.5.6.SEC03.jar
org.springframework.beans-2.5.6.SEC03.jar
org.springframework.context-2.5.6.SEC03.jar
org.springframework.core-2.5.6.SEC03.jar
slf4j-api-1.6.4.jar
spring-osgi-core-1.2.1.jar
spring-osgi-extender-1.2.1.jar
spring-osgi-io-1.2.1.jar
spring-osgi-mock-1.2.1.jar