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