OSGI服务发布和导入的自主实现
—OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]之二
在《OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]》一文中,我提出了非SpringDM的OSGI下使用Spring的解决方案。
本文是该文的姐妹篇,讲解在“OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]”下的OSGI服务的发布和导入的实现。
OSGI服务的发布
OSGI下服务的发布,仍然和SpringDM下的相同。
如:
<service ref="beanToPublish" interface="com.xyz.MessageService"/>
<service id="myServiceRegistration" ref="beanToPublish"
interface="com.xyz.MessageService"/>
<osgi:service interface="com.xyz.MessageService">
<bean class="SomeClass">
...
</bean>
</osgi:service>
<osgi:service ref="beanToBeExported" interface="com.xyz.MessageService"/>
<bean id="beanToBeExported" scope="bundle" class="com.xyz.MessageServiceImpl"/>
完全相同。不需改变。
我一向不喜欢自制Spring标签,如上面的osgi:service
自制Spring标签,虽然看上去挺酷,很专业。但是确实增加了我们用户的学习强度。你必须看文档才能知道该怎样使用这些千奇百怪的标签。
我还是喜欢直接使用<bean>标签。实际上,SpringDM中负责注册服务的类是:org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean类。
因此,我们可以这样注册OSGI服务:
例1
<bean id="userBySessionServiceOsgiService" class="org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean">
<property name="target">
<ref bean="userBySessionService"/>
</property>
<property name="interfaces">
<util:list>
<value>com.withub.gis.server.login.IUserBySessionService</value>
</util:list>
</property>
</bean>
例2
<bean id="loginWSSecurityOsgiService" class="org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean">
<property name="target">
<ref bean="loginWSSecurity"/>
</property>
<property name="interfaces">
<util:list>
<value>com.withub.gis.server.login.ILoginWSSecurity</value>
</util:list>
</property>
</bean>
OSGI服务的导入
在我的解决方案下,再使用SpringDM的导入服务的方式就不行了,会报错。这应该是SpringDM内部实现造成的。
SpringDM下的org.springframework.osgi.service.importer.support. OsgiServiceProxyFactoryBean导入一个服务。
OsgiServiceCollectionProxyFactoryBean导入多个服务。
我们需要编写自己的导入OSGI服务的类
导入OSGI Service的类
这是自己独立于SpringDM的OSGI服务导入类。
/**
*
*/
package com.withub.gis.osgi.util.springSupport.importService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
/**
* @author 沈东良 Edward Shen shendl_s@hotmail.com
*
*/
public class ImportOsgiServiceFactory implements IImportOsgiServiceFactory {
/* (non-Javadoc)
* @see com.withub.gis.osgi.util.springSupport.importService.IImportOsgiServiceFactory#getService()
*/
public Object getService(){
Object[] services=this.getServices();
if(services.length>=1){
return services[0];
}else{
return null;
}
}
public static int DefaultRetryTimes=1;
public static int DefaultWaitTime=1000;
private int retryTimes=DefaultRetryTimes;
private int waitTime=DefaultWaitTime;
public int getRetryTimes() {
return retryTimes;
}
public void setRetryTimes(int retryTimes) {
this.retryTimes = retryTimes;
}
public int getWaitTime() {
return waitTime;
}
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
/* (non-Javadoc)
* @see com.withub.gis.osgi.util.springSupport.importService.IImportOsgiServiceFactory#getServices()
*/
public Object[] getServices(){
List<ServiceReference> all=new ArrayList<ServiceReference>();
String interface0=this.interfaces[0];
ServiceTracker serviceTracker=new ServiceTracker(this.bundleContext,interface0 , null);
serviceTracker.open();
ServiceReference[] serviceReferences=serviceTracker.getServiceReferences();
if(serviceReferences==null && this.retryTimes>0){
this.retryTimes--;
try {
Thread.sleep(this.getWaitTime());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.getServices();
}
for(ServiceReference serviceReference:serviceReferences){
String[] objectClasses=(String[]) serviceReference.getProperty(Constants.OBJECTCLASS);
if(equal(this.interfaces,objectClasses)){
all.add(serviceReference);
}
}
if(this.map!=null){
for(ServiceReference serviceReference:all){
boolean upToGrade=true;