OSGi开发之Spring-OSGi(一)发布服务[原]
作者:coolflyr_reg 日期:2008-06-24 02:51:14
我使用的Spring-OSGi的版本是1.1.0-m2版本,下载下来按照压缩包里文档的说明,安装好PDE的开发环境,然后正式开始。
首先配置OSGi Framework的运行环境,我的Eclipse是3.3的,运行环境需要以下的Bundle:
操作步骤:点击菜单Run->Open Run Dialog…,在左侧的列表中,找到OSGi Framework,右键单击,New,修改Name为SpringOSGiDemo,并在Bundles选项卡中,选中以上列举的Bundle, 其中,有些Bundle在这个例子中并不需要,可以自己反复试验,看哪些需要哪些不需要。然后点击Apply,点Run。
在Console中会出现如下显示:
输入ss命令,安装的插件如下:
OK,这样我们的Spring-OSGi的环境就启动好了,现在先关闭它。我们来建立一个Plug-in Project,命名为:PublishServiceDemo。
首先新建一个接口:com.demo.MyService,代码如下:
接下来创建一个接口实现:com.demo.MyServiceImpl,代码如下:
在Plug-in ManiFest Editor中打开META-INF/MANIFEST.MF,如果安装了PDE,将会默认使用Plug-in ManiFest Editor打开。在Runtime标签中的Exported Packages中添加com.demo包,此时MANIFEST.MF文件中的内容如下:
注意:手工写MANIFEST.MF文件时,最后一行一定要有一个回车。
接下来我们要写Spring-OSGi的发布配置文件。在META-INF下建立文件夹并命名为:spring,然后新建一个xml文件:myservice.xml,文件内容如下:
注意:如果使用1.4的JDK,这里会出现讨厌的不支持xsd的验证错误,所以,请使用1.5以上的JDK,我使用的JDK是1.5的。
OK,我们现在完成了第一个通过Spring-OSGi的发布服务的Bundle。再次打开Open Run Dialog…,选择我们建立的SpringOSGiDemo的OSGi Framework的环境,在Bundles标签中选中我们的PublishServiceDemo,依次点击Apply,Run。
在Console中,会显示如下日志:
我们可以看到在打印出的日志中,倒数第五行是: Create MyServiceImpl. 这是我们在MyServiceImpl类中的构造函数里打印的语句,这说明了我们的服务实例被创建了。最后一行我们可以看到Spring-OSGi框架提示我们发布了OSGi Service。现在我们在命令行里输入:ss,将看到如下显示:
我们可以看到,这里编号为42的Bundle是我们刚刚建立的PublishServiceDemo。那么我们的服务发布到OSGi环境中了么?再次在osgi>提示符后输入命令:bundle 42,将显示如下结果:
可以看到,在Registered Services中有这样一句:
这说明,我们的服务成功的发布到OSGi环境中了。可以再输入命令status来查看所有发布的服务。
这是Spring-OSGi的第一个服务。很简单吧,不过通过测试发现,通过反复install和uninstall发布服务的Bundle,Spring-OSGi框架会报出ClassNotFoundException,看来Spring-OSGi的发布服务还是不能做到动态发布,这一点上还是Declarative Services更好一些。
下一次,我们来看看在OSGi框架中如何配置log4j。
首先配置OSGi Framework的运行环境,我的Eclipse是3.3的,运行环境需要以下的Bundle:
1 | ? org.apache.commons.logging ? org.eclipse.osgi ? org.springframework.bundle.osgi.core ? org.springframework.bundle.osgi.extender ? org.springframework.bundle.osgi.io ? org.springframework.bundle.spring.aop ? org.springframework.bundle.spring.beans ? org.springframework.bundle.spring.context ? org.springframework.bundle.spring.context.support ? org.springframework.bundle.spring.core ? org.springframework.osgi.aopalliance.osgi ? org.springframework.osgi.backport-util-concurrent.osgi ? org.springframework.osgi.log4j.osgi ? org.springframework.osgi.servlet-api.osgi ? slf4j.api ? slf4j.log4j12 |
操作步骤:点击菜单Run->Open Run Dialog…,在左侧的列表中,找到OSGi Framework,右键单击,New,修改Name为SpringOSGiDemo,并在Bundles选项卡中,选中以上列举的Bundle, 其中,有些Bundle在这个例子中并不需要,可以自己反复试验,看哪些需要哪些不需要。然后点击Apply,点Run。
在Console中会出现如下显示:
1 | osgi> 2008-6-24 1:33:02 org.springframework.osgi.extender.internal.activator.ContextLoaderListener start 信息: Starting [org.springframework.bundle.osgi.extender] bundle v.[1.1.0.m2] 2008-6-24 1:33:02 org.springframework.osgi.extender.internal.support.ExtenderConfiguration <init> 信息: No custom configuration detected; using defaults 2008-6-24 1:33:02 org.springframework.osgi.extender.internal.activator.ContextLoaderListener addDefaultPostProcessors 信息: Disabled automatic Spring-DM annotation processing; [ org.springframework.osgi.extender.annotation.auto.processing=null] |
输入ss命令,安装的插件如下:
1 | ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828 1 ACTIVE org.springframework.bundle.osgi.io_1.1.0.m2 2 ACTIVE org.springframework.bundle.osgi.extender_1.1.0.m2 3 ACTIVE org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT 4 ACTIVE org.springframework.bundle.spring.beans_2.5.4 5 ACTIVE org.springframework.bundle.spring.context_2.5.4 6 ACTIVE org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT 7 ACTIVE org.springframework.osgi.backport-util-concurrent.osgi_3.1.0.SNAPSHOT 8 ACTIVE org.springframework.bundle.spring.aop_2.5.4 9 ACTIVE org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT 10 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2 12 ACTIVE slf4j.api_1.4.3 13 ACTIVE slf4j.log4j12_1.4.3 14 ACTIVE org.springframework.bundle.spring.core_2.5.4 15 ACTIVE org.springframework.bundle.spring.context.support_2.5.4 16 ACTIVE org.apache.commons.logging_1.0.4.v200706111724 osgi> |
OK,这样我们的Spring-OSGi的环境就启动好了,现在先关闭它。我们来建立一个Plug-in Project,命名为:PublishServiceDemo。
首先新建一个接口:com.demo.MyService,代码如下:
1 | package com.demo;
public interface MyService
{
public String getName();
}
|
接下来创建一个接口实现:com.demo.MyServiceImpl,代码如下:
1 | package com.demo.impl;
import com.demo.MyService;
public class MyServiceImpl implements MyService
{
public MyServiceImpl()
{
System.out.println("Create MyServiceImpl.");
}
public String getName()
{
return "this is MyService";
}
}
|
在Plug-in ManiFest Editor中打开META-INF/MANIFEST.MF,如果安装了PDE,将会默认使用Plug-in ManiFest Editor打开。在Runtime标签中的Exported Packages中添加com.demo包,此时MANIFEST.MF文件中的内容如下:
1 | Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: PublishServiceDemo Plug-in Bundle-SymbolicName: PublishServiceDemo Bundle-Version: 1.0.0 Export-Package: com.demo |
注意:手工写MANIFEST.MF文件时,最后一行一定要有一个回车。
接下来我们要写Spring-OSGi的发布配置文件。在META-INF下建立文件夹并命名为:spring,然后新建一个xml文件:myservice.xml,文件内容如下:
1 | <?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"
xmlns:beans="http://www.springframework.org/schema/beans"
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">
<osgi:service id="myServiceOsgi" ref="myService" interface="com.demo.MyService"/>
<bean name="myService" class="com.demo.impl.MyServiceImpl"/>
</beans>
|
注意:如果使用1.4的JDK,这里会出现讨厌的不支持xsd的验证错误,所以,请使用1.5以上的JDK,我使用的JDK是1.5的。
OK,我们现在完成了第一个通过Spring-OSGi的发布服务的Bundle。再次打开Open Run Dialog…,选择我们建立的SpringOSGiDemo的OSGi Framework的环境,在Bundles标签中选中我们的PublishServiceDemo,依次点击Apply,Run。
在Console中,会显示如下日志:
1 | osgi> 2008-6-24 2:14:05 org.springframework.osgi.extender.internal.activator.ContextLoaderListener start
信息: Starting [org.springframework.bundle.osgi.extender] bundle v.[1.1.0.m2]
2008-6-24 2:14:05 org.springframework.osgi.extender.internal.support.ExtenderConfiguration <init>
信息: No custom configuration detected; using defaults
2008-6-24 2:14:05 org.springframework.osgi.extender.internal.activator.ContextLoaderListener addDefaultPostProcessors
信息: Disabled automatic Spring-DM annotation processing; [ org.springframework.osgi.extender.annotation.auto.processing=null]
2008-6-24 2:14:05 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@f6dc61: display name [OsgiBundleXmlApplicationContext(bundle=PublishServiceDemo, config=osgibundle:/META-INF/spring/*.xml)]; startup date [Tue Jun 24 02:14:05 CST 2008]; root of context hierarchy
2008-6-24 2:14:05 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [bundleentry://42/META-INF/spring/myservice.xml]
2008-6-24 2:14:05 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@f6dc61]: org.springframework.beans.factory.support.DefaultListableBeanFactory@bbf341
2008-6-24 2:14:05 org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor stageOne
信息: No outstanding OSGi service dependencies, completing initialization for OsgiBundleXmlApplicationContext(bundle=PublishServiceDemo, config=osgibundle:/META-INF/spring/*.xml)
2008-6-24 2:14:05 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@bbf341: defining beans [myServiceOsgi,myService]; root of factory hierarchy
Create MyServiceImpl.
2008-6-24 2:14:05 org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean registerService
信息: Publishing service under classes [{com.demo.MyService}]
2008-6-24 2:14:05 org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext publishContextAsOsgiServiceIfNecessary
信息: Publishing application context as OSGi service with properties {org.springframework.context.service.name=PublishServiceDemo, Bundle-SymbolicName=PublishServiceDemo, Bundle-Version=1.0.0}
|
我们可以看到在打印出的日志中,倒数第五行是: Create MyServiceImpl. 这是我们在MyServiceImpl类中的构造函数里打印的语句,这说明了我们的服务实例被创建了。最后一行我们可以看到Spring-OSGi框架提示我们发布了OSGi Service。现在我们在命令行里输入:ss,将看到如下显示:
1 | ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828 1 ACTIVE org.springframework.bundle.osgi.io_1.1.0.m2 2 ACTIVE org.springframework.bundle.osgi.extender_1.1.0.m2 3 ACTIVE org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT 4 ACTIVE org.springframework.bundle.spring.beans_2.5.4 5 ACTIVE org.springframework.bundle.spring.context_2.5.4 6 ACTIVE org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT 7 ACTIVE org.springframework.osgi.backport-util-concurrent.osgi_3.1.0.SNAPSHOT 8 ACTIVE org.springframework.bundle.spring.aop_2.5.4 9 ACTIVE org.springframework.osgi.aopalliance.osgi_1.0.0.SNAPSHOT 10 ACTIVE org.springframework.bundle.osgi.core_1.1.0.m2 12 ACTIVE slf4j.api_1.4.3 13 ACTIVE slf4j.log4j12_1.4.3 14 ACTIVE org.springframework.bundle.spring.core_2.5.4 15 ACTIVE org.springframework.bundle.spring.context.support_2.5.4 16 ACTIVE org.apache.commons.logging_1.0.4.v200706111724 42 ACTIVE PublishServiceDemo_1.0.0 osgi> |
我们可以看到,这里编号为42的Bundle是我们刚刚建立的PublishServiceDemo。那么我们的服务发布到OSGi环境中了么?再次在osgi>提示符后输入命令:bundle 42,将显示如下结果:
1 | osgi> bundle 42
initial@reference:file:../../../../../../../../Documents/workspace/PublishServiceDemo/ [42]
Id=42, Status=ACTIVE Data Root=/Users/ttt/Documents/workspace/.metadata/.plugins/org.eclipse.pde.core/SpringOSGiFramework/org.eclipse.osgi/bundles/42/data
Registered Services
{com.demo.MyService}={org.springframework.osgi.bean.name=myService, Bundle-SymbolicName=PublishServiceDemo, Bundle-Version=1.0.0, service.id=23}
{org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=PublishServiceDemo, Bundle-SymbolicName=PublishServiceDemo, Bundle-Version=1.0.0, service.id=24}
Services in use:
{org.springframework.beans.factory.xml.NamespaceHandlerResolver}={service.id=21}
{org.xml.sax.EntityResolver}={service.id=22}
Exported packages
com.demo; version="0.0.0"[exported]
No imported packages
No fragment bundles
Named class space
PublishServiceDemo; bundle-version="1.0.0"[provided]
No required bundles
osgi>
|
可以看到,在Registered Services中有这样一句:
1 | {com.demo.MyService}={org.springframework.osgi.bean.name=myService, Bundle-SymbolicName=PublishServiceDemo, Bundle-Version=1.0.0, service.id=23}
|
这说明,我们的服务成功的发布到OSGi环境中了。可以再输入命令status来查看所有发布的服务。
这是Spring-OSGi的第一个服务。很简单吧,不过通过测试发现,通过反复install和uninstall发布服务的Bundle,Spring-OSGi框架会报出ClassNotFoundException,看来Spring-OSGi的发布服务还是不能做到动态发布,这一点上还是Declarative Services更好一些。
下一次,我们来看看在OSGi框架中如何配置log4j。
平均得分
(0 次评分)
评论: 0 | 查看次数: 229
发表评论
订阅
上一篇
|

文章来自:
标签: 




