订阅所有JSP/Servlet的日志 订阅 | 这是最新一篇日志 上一篇 | 下一篇日志 下一篇 ]
插件技术

OSGi开发之Spring-OSGi(一)发布服务[原]

我使用的Spring-OSGi的版本是1.1.0-m2版本,下载下来按照压缩包里文档的说明,安装好PDE的开发环境,然后正式开始。

首先配置OSGi Framework的运行环境,我的Eclipse是3.3的,运行环境需要以下的Bundle:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
?	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
2
3
4
5
6
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
2
3
4
5
6
package com.demo;
 
public interface MyService
{
    public String getName();
}


接下来创建一个接口实现:com.demo.MyServiceImpl,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
2
3
4
5
6
7
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
2
3
4
5
6
7
8
9
10
11
12
13
<?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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 次评分)





文章来自: 本站原创
标签: OSGi Spring-OSGi 
评论: 0 | 查看次数: 229
发表评论
昵 称:  登录
内 容:
选 项:
字数限制 1000 字 | UBB代码 开启 | [img]标签 开启