基于Spring-OSGi应用开发杂谈
关键字: spring osgi 在Spring大行其道的今天,网络上随便找一款Java Web应用很难说它的身上没有Spring的影子,前些日子说到OSGi在系统模块化封装、系统热插拔等方面有其独特的优势,那么如果在Spring的Ioc和AOP的支撑下,如果可以将Spring与OSGi结合在一起那会怎么样呢:
1). 能够更好的分离应用逻辑与模块
2). 具备同时部署一个模块的多个版本的功能
3). 具备动态查找,使用其他系统模块功能的能力
4). 在运行时动态部署,升级和卸载模块的能力
5). 在Spring框架下,实现模块之间实例化、配置、集成和装饰组件的能力
6). 在简单的编程模式下快速开发OSGi应用
基于对OSGi在软件开发中的优势考虑,Spring的设计开发团队为了能够支持OSGi的开发,在其架构中内置了Spring-OSGi模块,Spring’OSGi的目标是使得写基于Spring的应用程序尽可能的容易,这些应用可以部署到OSGi的执行环境中,并可有效利用OSGi框架所提供的服务。通过在易用、强大的Spring框架上构建应用程序,Spring对OSGi的支持也使得开发这样的基于OSGi的应用更加简单、更加高效。Spring’s OSGi的目标并不是提供一个通用的模型以支持任意的基于OSGi的应用程序开发,但是某些OSGi的开发者肯定能够发现Spring模型吸引人之处,并采纳它。目前已经存在的OSGi的bundles以及它们所export的任何服务都可以轻松的集成到使用SpringOSGi支撑的应用中,就象是Spring已经存在的配置项。
Spring OSGi定位于OSGi R4及以上版本,JDK1.3及以上版本。这个规范假设读者已经具有一定的Spring及OSGi的知识。参见介绍白皮书“OSGi for Spring developers”以及“Spring for OSGi developers”。
OSGi中的开发单元(以及模块单元)是bundle。OSGi中所说的bundle有三种稳定状态:installed,resolved,active。而在一个Bundle处于Active状态中时,说明该Bundle已经处于可用状态。
为了能够能够简明扼要的说明Spring-OSGi的结合使用,因此我们建立一个小小的test工程:
1). 在Eclipse中利用m2eclipse插件建立一个Maven工程(内容如下):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.danlley.osgi.spring.test</groupId> <artifactId>osgi_spring_test</artifactId> <name/> <version>0.0.1-SNAPSHOT</version> <description/> </project>
2). 利用PDE Tools将工程转化为一个Plug-in Projects。转化成功后会在系统中增加一个目录和两个文件,一个是build.properties,一个是在新增加的目录META-INF下的MANIFEST.MF文件。
a. MANIFEST.MF文件内容:
----------------------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: osgi_spring_test
Bundle-SymbolicName: osgi_spring_test
Bundle-Version: 1.0.0
----------------------------------------
b. build.properties文件内容:
----------------------------------------
source.. = src/main/java/,\
src/test/java/,\
src/main/resources/,\
src/test/resources/
bin.includes = META-INF/,\
.
----------------------------------------
c. 编写示例代码:
MyFirstSpringServiceImpl
package org.danlley.osgi.impl;
import org.danlley.osgi.service.MyFirstSpringService;
public class MyFirstSpringServiceImpl implements MyFirstSpringService {
public MyFirstSpringServiceImpl() {
System.out.println("MyFirstSpringService>> constructor initialized!");
sayHelloToEveryBody();
}
public void sayHelloToEveryBody() {
System.out.println("method sayHelloToEveryBody() has been called.");
System.out.println("sayHelloToEveryBody>> Hello Everyone!");
}
}
MyFirstSpringService
package org.danlley.osgi.service;
public interface MyFirstSpringService {
public void sayHelloToEveryBody();
}
d. 在META-INF目录下建立Spring目录增加文件:
fooservice.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="mySpringService" class="org.danlley.osgi.impl.MyFirstSpringServiceImpl" /> </beans>
fooservice-osgi.xml
<?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"> <osgi:service id="mySpringServiceOsgi" ref="mySpringService" interface="org.danlley.osgi.service.MyFirstSpringService" /> </beans>
e. 修改POM文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.danlley.osgi.spring.test</groupId> <artifactId>osgi_spring_test</artifactId> <name/> <version>0.0.1-SNAPSHOT</version> <description/> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.0</version> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestFile> META-INF/MANIFEST.MF </manifestFile> </archive> </configuration> </plugin> </plugins> </build> <pluginRepositories> <pluginRepository> <id>maven-repo</id> <name>maven repo</name> <url>http://repo1.maven.org/maven2/</url> </pluginRepository> <pluginRepository> <id>agilejava</id> <url>http://agilejava.com/maven/</url> </pluginRepository> </pluginRepositories> <repositories> <repository> <id>eclipse-repository</id> <name>Eclipse Repository</name> <url>http://repo1.maven.org/eclipse/</url> </repository> <repository> <id>safehaus-repository</id> <name>Safehaus Repository</name> <url>http://m2.safehaus.org</url> </repository> <repository> <id>spring-ext</id> <name>Spring External Dependencies Repository</name> <url> http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext/ </url> </repository> <repository> <id>spring-release</id> <name>Spring Portfolio Release Repository</name> <url> http://s3.amazonaws.com/maven.springframework.org/release </url> </repository> <repository> <id>spring-external</id> <name>Spring Portfolio Release Repository</name> <url> http://s3.amazonaws.com/maven.springframework.org/external </url> </repository> <repository> <id>spring-milestone</id> <name>Spring Portfolio Milestone Repository</name> <url> http://s3.amazonaws.com/maven.springframework.org/milestone </url> </repository> <repository> <id>i21-s3-osgi-repo</id> <name>i21 osgi artifacts repo</name> <snapshots> <enabled>true</enabled> </snapshots> <url> http://s3.amazonaws.com/maven.springframework.org/osgi </url> </repository> </repositories> </project>
f. 配置一些支持OSGi运行环境的一些Bundle
-----------------------------------------------------------------------------------------
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.2.R33x_v20080105
6 ACTIVE org.eclipse.osgi.services_3.1.200.v20070605
30 ACTIVE org.apache.commons.logging_1.0.4.v200706111724
34 ACTIVE org.apache.commons.logging_1.0.4
35 ACTIVE org.springframework.bundle.spring_2.5.2.v200803070100
36 ACTIVE org.springframework.osgi.backport.util.concurrent_3.0.0
37 ACTIVE org.eclipse.equinox.ds_1.0.0.qualifier
38 ACTIVE org.springframework.bundle.osgi.core_1.0.1.v200803070100
39 ACTIVE org.springframework.bundle.osgi.io_1.0.1.v200803070100
40 ACTIVE osgi_spring_test_1.0.0
41 ACTIVE org.springframework.bundle.osgi.extender_1.0.1.v200803070100
42 ACTIVE org.springframework.binding_1.0.3.1
-----------------------------------------------------------------------------------------
配置后MANIFEST.MF文件内容如下:
------------------------------------------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: osgi_spring_test
Bundle-SymbolicName: osgi_spring_test
Bundle-Version: 1.0.0
Require-Bundle: org.eclipse.osgi,
org.springframework.bundle.osgi.core,
org.springframework.bundle.osgi.io,
org.springframework.bundle.osgi.extender,
org.springframework.bundle.spring,
org.springframework.osgi.backport.util.concurrent,
org.apache.commons.logging,
org.springframework.binding,
org.eclipse.equinox.ds,
org.eclipse.osgi.services
------------------------------------------------------------
3. 运行结果:
-----------------------------------------------------------------------------------------
osgi> Jul 22, 2008 10:54:39 AM org.springframework.osgi.extender.internal.ContextLoaderListener start
INFO: Starting org.springframework.osgi.extender bundle v.[1.0.1.v200803070100]
Jul 22, 2008 10:54:40 AM org.springframework.osgi.extender.internal.ContextLoaderListener addAnnotationBPP
INFO: Disabled automatic Spring-DM annotation processing; [ org.springframework.osgi.extender.annotation.auto.processing=null]
Jul 22, 2008 10:54:40 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@482923 : display name [OsgiBundleXmlApplicationContext(bundle=osgi_spring_test, config=osgibundle:/META-INF/spring/*.xml)]; startup date [Tue Jul 22 10:54:40 CST 2008]; root of context hierarchy
Jul 22, 2008 10:54:40 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [bundleentry://40/META-INF/spring/fooservice-osgi.xml]
Jul 22, 2008 10:54:41 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [bundleentry://40/META-INF/spring/fooservice.xml]
Jul 22, 2008 10:54:41 AM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@482923]: org.springframework.beans.factory.support.DefaultListableBeanFactory@18ce14a
Jul 22, 2008 10:54:41 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@18ce14a : defining beans [mySpringServiceOsgi,mySpringService]; root of factory hierarchy
MyFirstSpringService>> constructor initialized!<-----------------关键信息开始
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!<-----------------关键信息结束
Jul 22, 2008 10:54:41 AM org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean registerService
INFO: Publishing service under classes [{org.danlley.osgi.service.MyFirstSpringService}]
Jul 22, 2008 10:54:41 AM org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext publishContextAsOsgiServiceIfNecessary
INFO: Publishing application context with properties (org.springframework.context.service.name=osgi_spring_test)
-----------------------------------------------------------------------------------------
下面,我们对刚才运行的Spring-osgi示例进行分析和说明,缺省情况下,Spring将使用在META-INF/spring文件夹中的所有以“.xml”为扩展名的文档,作为application context的配置定义。当然,这个缺省设置是可以在manifest header中重写的,关于这个话题不是我们这里的重点,不过我会在以后的文章中涉及到这个议题。
接下来编写测试用例:
package org.danlley.osgi.impl;
import junit.framework.TestCase;
import org.danlley.osgi.service.MyFirstSpringService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MyFirstSpringServiceImplTest extends TestCase {
private ApplicationContext ac;
public void setUp() {
ac = new FileSystemXmlApplicationContext(
"META-INF/spring/fooservice.xml");
}
public void testSayHelloToEveryBody() {
MyFirstSpringService _service=(MyFirstSpringService)ac.getBean("mySpringService");
System.out.println("++++++++++++++++++++++++++++++++++++");
_service.sayHelloToEveryBody();
System.out.println("++++++++++++++++++++++++++++++++++++");
}
}
运行测试用例,运行结果如下:
-----------------------------------------------------------------------------------
2008-7-22 15:13:47 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@108786b : display name [org.springframework.context.support.FileSystemXmlApplicationContext@108786b]; startup date [Tue Jul 22 15:13:47 CST 2008]; root of context hierarchy
2008-7-22 15:13:47 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:\workspace\osgi_spring_test\META-INF\spring\fooservice.xml]
2008-7-22 15:13:47 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@108786b]: org.springframework.beans.factory.support.DefaultListableBeanFactory@37fb1e
2008-7-22 15:13:47 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@37fb1e : defining beans [mySpringService,mySecondService]; root of factory hierarchy
MyFirstSpringService>> constructor initialized!
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
second service was called! <-----------------关键信息结束
++++++++++++++++++++++++++++++++++++
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
++++++++++++++++++++++++++++++++++++<-----------------关键信息结束
-----------------------------------------------------------------------------------
4. 实例扩展:
由于我们在这里使用的是硬加载的方式,因此不失一般性,在增加一个Bean。代码如下:
MySecondSpringServiceImpl
package org.danlley.osgi.impl;
import org.danlley.osgi.service.MyFirstSpringService;
import org.danlley.osgi.service.MySecondSpringService;
public class MySecondSpringServiceImpl implements MySecondSpringService {
MyFirstSpringService mySpringService;
public MySecondSpringServiceImpl() {
System.out.println("second service was called! ");
}
public void helloWatcher() {
if (mySpringService == null) {
System.out.println("initialization failed");
} else {
System.out.println("-------------------------------------");
mySpringService.sayHelloToEveryBody();
System.out.println("-------------------------------------");
}
}
public MyFirstSpringService getMySpringService() {
return mySpringService;
}
public void setMySpringService(MyFirstSpringService mySpringService) {
this.mySpringService = mySpringService;
}
}
MySecondSpringService
package org.danlley.osgi.service;
public interface MySecondSpringService {
public void helloWatcher();
}
修改相应配置文件,内容如下:
fooservice.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="mySpringService" class="org.danlley.osgi.impl.MyFirstSpringServiceImpl" /> <bean name="mySecondService" class="org.danlley.osgi.impl.MySecondSpringServiceImpl" > <property name="mySpringService"> <ref bean="mySpringService"/> </property> </bean> </beans>
fooservice-osgi.xml
<?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"> <osgi:service id="mySpringServiceOsgi" ref="mySpringService" interface="org.danlley.osgi.service.MyFirstSpringService" /> <osgi:service id="mySecondServiceOsgi" ref="mySecondService" interface="org.danlley.osgi.service.MySecondSpringService" /> </beans>
为MySecondSpringService编写测试用例:
package org.danlley.osgi.impl;
import junit.framework.TestCase;
import org.danlley.osgi.service.MySecondSpringService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MySecondSpringServiceImplTest extends TestCase {
private ApplicationContext ac;
public void setUp() {
ac = new FileSystemXmlApplicationContext(
"META-INF/spring/fooservice.xml");
}
public void testHelloWatcher() {
try {
MySecondSpringService _service=(MySecondSpringService)ac.getBean("mySecondService");
System.out.println("++++++++++++++++++++++++++++++++++++");
_service.helloWatcher();
System.out.println("++++++++++++++++++++++++++++++++++++");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果如下:
-----------------------------------------------------------------------------------------
2008-7-22 15:16:31 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@1add2dd : display name [org.springframework.context.support.FileSystemXmlApplicationContext@1add2dd]; startup date [Tue Jul 22 15:16:31 CST 2008]; root of context hierarchy
2008-7-22 15:16:31 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:\workspace\osgi_spring_test\META-INF\spring\fooservice.xml]
2008-7-22 15:16:31 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@1add2dd]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1543c88
2008-7-22 15:16:31 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1543c88 : defining beans [mySpringService,mySecondService]; root of factory hierarchy
MyFirstSpringService>> constructor initialized!
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
second service was called!
++++++++++++++++++++++++++++++++++++
-------------------------------------
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
-------------------------------------
++++++++++++++++++++++++++++++++++++
-----------------------------------------------------------------------------------------
5. 客户端Bundle调用
从上面的验证可以看出,我们配置的Spring是没有问题的,那么是不是当前的Bundle已经可以被其他的Bundle使用了呢,让我们继续做一些小手术。
1). 发布包路径,发布成功后的MANIFEST.MF配置文件内容如下
---------------------------------------------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: osgi_spring_test
Bundle-SymbolicName: osgi_spring_test
Bundle-Version: 1.0.0
Require-Bundle: org.eclipse.osgi,
org.springframework.bundle.osgi.core,
org.springframework.bundle.osgi.io,
org.springframework.bundle.osgi.extender,
org.springframework.bundle.spring,
org.springframework.osgi.backport.util.concurrent,
org.apache.commons.logging,
org.springframework.binding,
org.eclipse.equinox.ds,
org.eclipse.osgi.services
Export-Package: org.danlley.osgi.service
---------------------------------------------------------------
2). 建立一个客户端Bundle,大体跟上面建立工程的过程类似,这里就不再详述。
3). 在新建工程中增加类如下:
Activator
package org.danlley.osgi.spring.client;
import org.danlley.osgi.service.MyFirstSpringService;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Activator implements BundleActivator {
public void start(final BundleContext context) throws Exception {
System.out.println("开始启动bundle。。。。");
Thread t = new Thread(new Runnable() {
boolean registered = false;
ServiceReference ref = null;
int safety = 0;
public void run() {
while (!registered && safety < 10) {
System.out.println("Trying to get the reference to FooService");
ref = context.getServiceReference(MyFirstSpringService.class.getName());
if (ref != null) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
safety++;
}
if (ref == null) {
System.out.println("Service " + MyFirstSpringService.class.getName() + " is not registered");
} else {
System.out.println("Found service");
MyFirstSpringService service = (MyFirstSpringService) context.getService(ref);
System.out.println("Retrieved service: " + service.getClass().getName());
System.out.println("||||||||||||||||||||||||||||||||||||||||||||||");
service.sayHelloToEveryBody();
System.out.println("||||||||||||||||||||||||||||||||||||||||||||||");
}
}
});
t.start();
}
public void stop(BundleContext context) throws Exception {
System.out.println("Stopping service");
}
}
如果前面没有发布包路径,在这里可能会有些小麻烦。
4). 修改客户端工程的MANIFEST.MF配置文件
---------------------------------------------------------------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: osgi_spring_client
Bundle-SymbolicName: osgi_spring_client
Bundle-Version: 1.0.0
Require-Bundle: org.eclipse.osgi,
org.springframework.bundle.osgi.core,
org.springframework.bundle.osgi.io,
org.springframework.bundle.osgi.extender,
org.springframework.bundle.spring,
org.springframework.osgi.backport.util.concurrent,
org.apache.commons.logging,
org.springframework.binding,
org.eclipse.equinox.ds,
org.eclipse.osgi.services,
osgi_spring_test
Bundle-Activator: org.danlley.osgi.spring.client.Activator
---------------------------------------------------------------------------------
5). 运行客户端工程, 结果如下:
------------------------------------------------------------------------------------------------------------
osgi> Jul 22, 2008 4:11:20 PM org.springframework.osgi.extender.internal.ContextLoaderListener start
INFO: Starting org.springframework.osgi.extender bundle v.[1.0.1.v200803070100]
Jul 22, 2008 4:11:20 PM org.springframework.osgi.extender.internal.ContextLoaderListener addAnnotationBPP
INFO: Disabled automatic Spring-DM annotation processing; [ org.springframework.osgi.extender.annotation.auto.processing=null]
Jul 22, 2008 4:11:20 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@122cdb6 : display name [OsgiBundleXmlApplicationContext(bundle=osgi_spring_test, config=osgibundle:/META-INF/spring/*.xml)]; startup date [Tue Jul 22 16:11:20 CST 2008]; root of context hierarchy
开始启动bundle。。。。
Trying to get the reference to FooService
Jul 22, 2008 4:11:20 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [bundleentry://43/META-INF/spring/fooservice-osgi.xml]
Jul 22, 2008 4:11:20 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [bundleentry://43/META-INF/spring/fooservice.xml]
Jul 22, 2008 4:11:20 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@122cdb6]: org.springframework.beans.factory.support.DefaultListableBeanFactory@18941f7
Jul 22, 2008 4:11:20 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@18941f7 : defining beans [mySpringServiceOsgi,mySecondServiceOsgi,mySpringService,mySecondService]; root of factory hierarchy
MyFirstSpringService>> constructor initialized!
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
Jul 22, 2008 4:11:20 PM org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean registerService
INFO: Publishing service under classes [{org.danlley.osgi.service.MyFirstSpringService}]
second service was called!
Jul 22, 2008 4:11:20 PM org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean registerService
INFO: Publishing service under classes [{org.danlley.osgi.service.MySecondSpringService}]
Jul 22, 2008 4:11:20 PM org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext publishContextAsOsgiServiceIfNecessary
INFO: Publishing application context with properties (org.springframework.context.service.name=osgi_spring_test)
Trying to get the reference to FooService
Found service
Retrieved service: org.danlley.osgi.impl.MyFirstSpringServiceImpl
||||||||||||||||||||||||||||||||||||||||||||||<-------------------------------- 调用开始
method sayHelloToEveryBody() has been called.
sayHelloToEveryBody>> Hello Everyone!
||||||||||||||||||||||||||||||||||||||||||||||<-------------------------------- 调用结束
------------------------------------------------------------------------------------------------------------
跟我们预期的结果一样,成功运行并调用了我们在osgi_spring_test_1.0.0中定义的Spring应用。
结束!
参考资料:http://www.springframework.org/
QQ群:9896150 【Java终结者】
发表评论
- 浏览: 39834 次

- 详细资料
搜索本博客
链接
最新评论
-
OSGi之前世今生
不得不收藏一下了
-- by lggege -
OSGi与JSF结合开发Java W ...
呵呵,不知道有人把RichFace和 OSGi集成没
-- by gembin -
管窥Java开发中OSGi组件的 ...
不解eclipse的插件为什么可以称“热插拔”,明明每装一个插件都要重启,应该是 ...
-- by Sam1860 -
管窥Java开发中OSGi组件的 ...
学习,学习
-- by zhuyx808 -
管窥Java开发中OSGi组件的 ...
经典收藏
-- by bengan






评论排行榜