- 浏览: 270528 次
- 性别:
- 来自: 新乡
文章分类
- 全部博客 (227)
- servciemix (10)
- db (18)
- javaTools (4)
- hibernate (31)
- web (3)
- spring (14)
- design pattern (4)
- java security (3)
- portal (1)
- ejb (6)
- session (2)
- java_lang (21)
- jbpm (29)
- struts (7)
- orgRights (2)
- project manager Jira (7)
- 跨库事务 (2)
- mysql (14)
- ubuntu (7)
- osgi (9)
- maven ant make (4)
- 分布式 高并发 高性能 (5)
- virgo-dm_server (0)
- osgi web (3)
- platform (1)
- smooks (1)
- business (1)
- 职场生涯 (14)
- Java编码格式 (2)
- web服务 (1)
- 计算机使用 (1)
- 健康工作生活的保障,工作中务必抛掉的不良心态 (4)
- 电信-网络监控 (1)
- 多线程-multithread (1)
- 海量数据-高性能 (2)
- Mybatis (1)
- web开发平台研发 (0)
- oracle (0)
- 应用服务器调优 (0)
- web前端 (0)
- servlet-jsp (0)
- tomcat (2)
- newtouch (1)
- portal_liferay (2)
- version control (1)
- apm-impact (2)
- tools (1)
- 研发管理 (1)
- 电商业务 (1)
- 生鲜电商市场调查 (0)
- PBX (0)
- 房东 (0)
最新评论
-
lifuchao:
...
权限问题 -
Branding:
谢谢,受教了,另外,CONN AS SYSDBA,必须是在操作 ...
Oracle密码忘记了怎么办? -
zhuchao_ko:
...
Portal实现原理 -
败类斯文:
不知道改哪里。。。木有见到红色。。表示悟性低了、、
jira error: Neither the JAVA_HOME nor the JRE_HOME environment variable is defin -
c__06:
正文:假如事务我是这样定义的: <tx:method n ...
Spring中Transactional配置
OSGI+Spring+Hibernate+...完美解决方案[非SpringDM] 2008-08-08
导论
最近,我做一个项目需要编写Eclipse的插件。我想在Eclipse插件中使用Spring和Hibernate。但却遇到了巨大的问题。
按照Spring组织的提示,我使用SpringDM1.02编写Spring程序(后来用SpringDM1.1,SpringDM又叫SpringOSGI)。但是总是遇到种种问题。特别是Spring管理下的Hibernate,总是无法找到Hibernate的配置文件。
到了后来,连Eclipse也挂了。每次重设Eclipse的目标插件集合的时候,Eclipse都会死掉!终于,我再也无法忍受SpringDM的折磨了!我告诉自己,是时候反思了!终于,我发现了SpringDM根本就是一个完全、彻底失败,无用的废物!所有的问题都是SpringDM造成的!而不是SpringDM所说的,OSGI,Hibernate等等其他软件造成的!我终于发现了OSGI+Spring+Hibernate+...完美解决方案。
问题的根源—ClassLoader
OSGI提供了自己的ClassLoader。每一个OSGI的插件,都有一个独立的ClassLoader被使用。这样就实现了各个插件的独立性。一个JVM上可以运行无数个OSGI插件,每一个OSGI插件都是独立的,除非发布为OSGI服务,或者发布自己Package。SpringDM的工作原理是这样子的:(我猜想的)
1.SpringDM是一个OSGI插件。作为一个一般的插件进行部署。
2.SpringDM一旦启动,就会探查所有其他Active状态的插件。
◦MANIFEST.MF中没有Spring的头,如果有,执行该配置。
◦如果MANIFEST.MF中没有Spring的头,探查META-INF/spring/目录下有没有.xml文件,如果有,它也是一个SpringDM项目。SpringDM探查其他插件的资源,应该使用的是这些插件的BundleContext对象来实现的。
另外,SpringDM应该注册了OSGI的事件,这样,其他插件启动,关闭,都会通知SpringDM。如果SpringDM发现一个插件是SpringDM插件。就导入该插件中的Spring配置文件,创建ApplicationContext。然后,把该ApplicationContext作为OSGI服务发布。如果插件中需要显式的getBean()方法获得对象,就使用它来获得。
SpringDM的问题
SpringDM的DM----动态管理,这个设计似乎很巧妙!刚开始我也被SpringDM的这一“强大功能”所折服。但是,实际上,SpringDM的所有问题根源,就在这里!
SpringDM实际上是在SpringDM这个插件中为所有Spring插件创建ApplicationContext的!显然,此时使用的ClassLoader是SpringDM这个插件的ClassLoader,而不是实际的Spring项目的插件的ClassLoader。并且,当前线程中的ClassLoader,也是SpringDM插件的ClassLoader。这样,就产生了问题。如,Hibernate,它内部使用当前线程中的ClassLoader来载入配置文件。
Thread.currentThread().getContextClassLoader()
绝大部分现有Java代码都使用这样的代码来获得ClassLoader来载入资源,动态创建类。现在,使用了SpringDM,所有这些代码的ClassLoader都会出现问题!都无法找到资源!
SpringDM的谎言
SpringDM的官方文档,把这些问题的责任推给了Hibernate和OSGI。它说,由于OSGI环境下ClassLoader的特殊性,因此使用Thread.currentThread().getContextClassLoader()得到的ClassLoader都是不正确的。应该使用BundleActivator接口的实现类的Classloader来得到正确的ClassLoader。而Hibernate这样的设计时未考虑OSGI环境的类库,在OSGI环境中出错是不可避免的。因此,Hibernate应该修改代码,以适应OSGI环境。而我上了Hibernate网站,没有看到HibernateOSGI项目。我看到有不少朋友在网上写了一些补丁代码,让Hibernate在SpringDM环境下正确运行。看来,我们还应该忙着修改数以亿行计的Java代码,把获得ClassLoader的代码修改掉,否则在SpringDM的OSGI环境下就会报错!
如果真是如此,OSGI真的没有存在的价值了!
事实
但是,事实并非如此!
如果不使用SpringDM,直接在OSGI插件中使用Hibernate,或者Thread.currentThread().getContextClassLoader(),都可以正确载入资源。因为,OSGI插件使用的ClassLoader是可以直接载入OSGI插件的所有资源的。并且,当前线程中的ClassLoader,也是当前OSGI插件使用的ClassLoader。因此,SpringDM在说谎!SpringDM的动态创建ApplicationContext的机制是一系列问题的源泉。
OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]
只要不使用SpringDM的动态创建ApplicationContext机制,就可以避免上述种种问题。试一下在BundleActivator接口中直接使用new ClassPathXmlApplicationContext()的方式创建ApplicationContext。结果失败了!通过Debug,我发现是Spring自己的一些特殊处理方式使它在OSGI环境下失败。然后,我研究了SpringDM1.1的API,找到了在插件中直接创建ApplicationContext的方法。
需要的环境:Spring的jar包,还有SpringDM1.1的core和extender的jar包。以及相应的依赖jar包。这些Jar包,可以放在插件中。也可以发布为一个OSGI插件,让所有需要创建ApplicationContext的插件依赖它。
源代码
ConfigableClassPathDefaultConfigurationScanner
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.osgi.framework.Bundle;
import org.springframework.osgi.extender.support.scanning.DefaultConfigurationScanner;
import org.springframework.osgi.io.OsgiBundleResource;
/**
* @author Edward Shen shendl_s@hotmail.com
*
*/
public class ConfigableClassPathDefaultConfigurationScanner extends
DefaultConfigurationScanner {
private String[] configFiles=null;
@Override
public String[] getConfigurations(Bundle bundle) {
String[] myConfigFiles=new String[configFiles.length];
for(int i=0;i<configFiles.length;i++){
String configFile=this.getConfigFiles()[i];
if(configFile.indexOf(":")==-1){
if(configFile.indexOf("/")!=0){
configFile="/"+configFile;
}
configFile="classpath:"+configFile;
}
myConfigFiles[i]=configFile;
}
this.setConfigFiles(myConfigFiles);
return myConfigFiles;
}
public String[] getConfigFiles() {
return configFiles;
}
public void setConfigFiles(String[] configFiles) {
this.configFiles = configFiles;
}
/**
*
*/
public ConfigableClassPathDefaultConfigurationScanner() {
// TODO Auto-generated constructor stub
}
public ConfigableClassPathDefaultConfigurationScanner(String[] configFiles) {
// TODO Auto-generated constructor stub
this.configFiles=configFiles;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
StandAloneOsgiBundleXmlApplicationContext
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.springframework.context.ApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
/**
* @author Edward Shen shendl_s@hotmail.com
*
*/
public class StandAloneOsgiBundleXmlApplicationContext extends
OsgiBundleXmlApplicationContext {
private String[] customConfigLocations=new String[]{};
@Override
public String[] getDefaultConfigLocations(){
return this.getCustomConfigLocations();
}
/**
*
*/
public StandAloneOsgiBundleXmlApplicationContext() {
// TODO Auto-generated constructor stub
}
/**
* @param parent
*/
public StandAloneOsgiBundleXmlApplicationContext(ApplicationContext parent) {
super(parent);
// TODO Auto-generated constructor stub
}
/**
* @param configLocations
*/
public StandAloneOsgiBundleXmlApplicationContext(String[] configLocations) {
super(configLocations);
this.setCustomConfigLocations(configLocations);
// TODO Auto-generated constructor stub
}
/**
* @param configLocations
* @param parent
*/
public StandAloneOsgiBundleXmlApplicationContext(String[] configLocations,
ApplicationContext parent) {
super(configLocations, parent);
this.setCustomConfigLocations(configLocations);
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public String[] getCustomConfigLocations() {
return customConfigLocations;
}
public void setCustomConfigLocations(String[] customConfigLocations) {
this.customConfigLocations = customConfigLocations;
}
}
StandAloneOsgiApplicationContextCreator
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
import org.springframework.osgi.extender.OsgiApplicationContextCreator;
import org.springframework.osgi.extender.support.ApplicationContextConfiguration;
import org.springframework.osgi.extender.support.scanning.ConfigurationScanner;
import org.springframework.osgi.util.OsgiStringUtils;
import org.springframework.util.ObjectUtils;
/**
* @author shendl_s@hotmail.com
*
*/
public class StandAloneOsgiApplicationContextCreator implements
OsgiApplicationContextCreator {
/** logger */
private static final Log log = LogFactory.getLog(StandAloneOsgiApplicationContextCreator.class);
private boolean publishContextAsService=true;
private ConfigurationScanner configurationScanner ;
private String[] configFiles=null;
public String[] getConfigFiles() {
return configFiles;
}
public void setConfigFiles(String[] configFiles) {
this.configFiles = configFiles;
}
/**
*
*/
public StandAloneOsgiApplicationContextCreator() {
}
public StandAloneOsgiApplicationContextCreator(String[] configFiles) {
this.setConfigFiles(configFiles);
}
/* (non-Javadoc)
* @see org.springframework.osgi.extender.OsgiApplicationContextCreator#createApplicationContext(org.osgi.framework.BundleContext)
*/
public DelegatedExecutionOsgiBundleApplicationContext createApplicationContext(
BundleContext bundleContext) throws Exception {
// TODO Auto-generated method stub
Bundle bundle = bundleContext.getBundle();
this.configurationScanner=new ConfigableClassPathDefaultConfigurationScanner(configFiles);
ApplicationContextConfiguration config = new ApplicationContextConfiguration(bundle, configurationScanner);
if (log.isTraceEnabled())
log.trace("Created configuration " + config + " for bundle "
+ OsgiStringUtils.nullSafeNameAndSymName(bundle));
// it's not a spring bundle, ignore it
log.info("Discovered configurations " + ObjectUtils.nullSafeToString(config.getConfigurationLocations())
+ " in bundle [" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "]");
String[] strs=config.getConfigurationLocations();
DelegatedExecutionOsgiBundleApplicationContext sdoac = new OsgiBundleXmlApplicationContext(
config.getConfigurationLocations());
sdoac.setBundleContext(bundleContext);
sdoac.setPublishContextAsService(this.isPublishContextAsService());
sdoac.refresh();
return sdoac;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public boolean isPublishContextAsService() {
return publishContextAsService;
}
public void setPublishContextAsService(boolean publishContextAsService) {
this.publishContextAsService = publishContextAsService;
}
}
OSGI插件中创建ApplicationContext的演示
/**
*
*@author Edward Shen shendl_s@hotmail.com
*
*/
public class Activator implements BundleActivator {
private ClassLoader classLoader = this.getClass().getClassLoader();
private Log log = LogFactory.getLog(this.getClass());
private DelegatedExecutionOsgiBundleApplicationContext applicationContext;
public DelegatedExecutionOsgiBundleApplicationContext getApplicationContext() {
return applicationContext;
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) {
System.out.println("com.withub.gis.client.service Startup!!");
String[] configFiles = new String[] { "spring/bean.xml",
"/spring/client.xml", "classpath:spring/osgi.xml" };
StandAloneOsgiApplicationContextCreator standAloneOsgiApplicationContextCreator = new StandAloneOsgiApplicationContextCreator(
configFiles);
try {
this.applicationContext = standAloneOsgiApplicationContextCreator
.createApplicationContext(context);
applicationContext.refresh();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Spring ApplicationContext Startup!!");
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
System.out.println("com.withub.gis.client.service Shutdown!!");
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
}
解释
1.上面的演示代码中,我是用spring目录下的文件作为Spring的配置文件。
我不建议你在META-INF/spring/目录下编写spring配置文件。否则,如果你的插件的部署环境中有SPringDM存在,那么就会创建2个ApplicationContext。
2.现在,你的Spring配置文件中如果使用了Hibernate,也仍然是正确无误的!
目前,使用的spring配置文件不能使用Ant风格的通配符。如果有哪位朋友对Spring源代码有研究,希望能加上这个功能。我还有项目要完成,目前只能做到这个程度了。我的代码使用了SPringDM提供的API。这是一个简单的办法。因为Spring内部的源代码太多,太复杂了。我现在的这个办法是最简单的。由于我使用了SPringDM的代码,因此,你应该了解SPringDM的一些资源搜索的策略。
OSGi Search Strategy Prefix Explanation
Class Space classpath: Searches the bundle classloader (the bundle, all imported packages and required bundles). Forces the bundle to be resolved. This method has similar semantics to Bundle#getResource(String) Class Space classpath*: Searches the bundle classloader (the bundle and all imported packages and required bundles).Forces the bundle to be resolved.This method has similar semantics to Bundle#getResources(String) JAR File (or JarSpace) osgibundlejar: Searches only the bundle jar.Provides low-level access without Bundles and Application Contexts Spring Dynamic Modules(1.1.0) 8 OSGi Search Strategy Prefix Explanation requiring the bundle to be resolved. Bundle Space osgibundle: Searches the bundle jar and its attached fragments (if there are any). Does not create a class loader or force the bundle to be resolved.
如果提供的SPring资源没有前缀,我就会为你增加classpath:前缀。经过试验,只有classpath:前缀的资源才可以被正确导入。
如,下面的配置
<context:property-placeholder location=" spring/jdbc.properties"/>
在一般的Spring程序中是可用的。(当然,spring目录下有jdbc.properties这个文件)但是在OSGI环境下,就会报错,告诉我找不到spring/jdbc.properties这个资源。必须加上classpath:前缀,
<context:property-placeholder location="classpath:/spring/jdbc.properties"/>
现在就正确了!
导论
最近,我做一个项目需要编写Eclipse的插件。我想在Eclipse插件中使用Spring和Hibernate。但却遇到了巨大的问题。
按照Spring组织的提示,我使用SpringDM1.02编写Spring程序(后来用SpringDM1.1,SpringDM又叫SpringOSGI)。但是总是遇到种种问题。特别是Spring管理下的Hibernate,总是无法找到Hibernate的配置文件。
到了后来,连Eclipse也挂了。每次重设Eclipse的目标插件集合的时候,Eclipse都会死掉!终于,我再也无法忍受SpringDM的折磨了!我告诉自己,是时候反思了!终于,我发现了SpringDM根本就是一个完全、彻底失败,无用的废物!所有的问题都是SpringDM造成的!而不是SpringDM所说的,OSGI,Hibernate等等其他软件造成的!我终于发现了OSGI+Spring+Hibernate+...完美解决方案。
问题的根源—ClassLoader
OSGI提供了自己的ClassLoader。每一个OSGI的插件,都有一个独立的ClassLoader被使用。这样就实现了各个插件的独立性。一个JVM上可以运行无数个OSGI插件,每一个OSGI插件都是独立的,除非发布为OSGI服务,或者发布自己Package。SpringDM的工作原理是这样子的:(我猜想的)
1.SpringDM是一个OSGI插件。作为一个一般的插件进行部署。
2.SpringDM一旦启动,就会探查所有其他Active状态的插件。
◦MANIFEST.MF中没有Spring的头,如果有,执行该配置。
◦如果MANIFEST.MF中没有Spring的头,探查META-INF/spring/目录下有没有.xml文件,如果有,它也是一个SpringDM项目。SpringDM探查其他插件的资源,应该使用的是这些插件的BundleContext对象来实现的。
另外,SpringDM应该注册了OSGI的事件,这样,其他插件启动,关闭,都会通知SpringDM。如果SpringDM发现一个插件是SpringDM插件。就导入该插件中的Spring配置文件,创建ApplicationContext。然后,把该ApplicationContext作为OSGI服务发布。如果插件中需要显式的getBean()方法获得对象,就使用它来获得。
SpringDM的问题
SpringDM的DM----动态管理,这个设计似乎很巧妙!刚开始我也被SpringDM的这一“强大功能”所折服。但是,实际上,SpringDM的所有问题根源,就在这里!
SpringDM实际上是在SpringDM这个插件中为所有Spring插件创建ApplicationContext的!显然,此时使用的ClassLoader是SpringDM这个插件的ClassLoader,而不是实际的Spring项目的插件的ClassLoader。并且,当前线程中的ClassLoader,也是SpringDM插件的ClassLoader。这样,就产生了问题。如,Hibernate,它内部使用当前线程中的ClassLoader来载入配置文件。
Thread.currentThread().getContextClassLoader()
绝大部分现有Java代码都使用这样的代码来获得ClassLoader来载入资源,动态创建类。现在,使用了SpringDM,所有这些代码的ClassLoader都会出现问题!都无法找到资源!
SpringDM的谎言
SpringDM的官方文档,把这些问题的责任推给了Hibernate和OSGI。它说,由于OSGI环境下ClassLoader的特殊性,因此使用Thread.currentThread().getContextClassLoader()得到的ClassLoader都是不正确的。应该使用BundleActivator接口的实现类的Classloader来得到正确的ClassLoader。而Hibernate这样的设计时未考虑OSGI环境的类库,在OSGI环境中出错是不可避免的。因此,Hibernate应该修改代码,以适应OSGI环境。而我上了Hibernate网站,没有看到HibernateOSGI项目。我看到有不少朋友在网上写了一些补丁代码,让Hibernate在SpringDM环境下正确运行。看来,我们还应该忙着修改数以亿行计的Java代码,把获得ClassLoader的代码修改掉,否则在SpringDM的OSGI环境下就会报错!
如果真是如此,OSGI真的没有存在的价值了!
事实
但是,事实并非如此!
如果不使用SpringDM,直接在OSGI插件中使用Hibernate,或者Thread.currentThread().getContextClassLoader(),都可以正确载入资源。因为,OSGI插件使用的ClassLoader是可以直接载入OSGI插件的所有资源的。并且,当前线程中的ClassLoader,也是当前OSGI插件使用的ClassLoader。因此,SpringDM在说谎!SpringDM的动态创建ApplicationContext的机制是一系列问题的源泉。
OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]
只要不使用SpringDM的动态创建ApplicationContext机制,就可以避免上述种种问题。试一下在BundleActivator接口中直接使用new ClassPathXmlApplicationContext()的方式创建ApplicationContext。结果失败了!通过Debug,我发现是Spring自己的一些特殊处理方式使它在OSGI环境下失败。然后,我研究了SpringDM1.1的API,找到了在插件中直接创建ApplicationContext的方法。
需要的环境:Spring的jar包,还有SpringDM1.1的core和extender的jar包。以及相应的依赖jar包。这些Jar包,可以放在插件中。也可以发布为一个OSGI插件,让所有需要创建ApplicationContext的插件依赖它。
源代码
ConfigableClassPathDefaultConfigurationScanner
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.osgi.framework.Bundle;
import org.springframework.osgi.extender.support.scanning.DefaultConfigurationScanner;
import org.springframework.osgi.io.OsgiBundleResource;
/**
* @author Edward Shen shendl_s@hotmail.com
*
*/
public class ConfigableClassPathDefaultConfigurationScanner extends
DefaultConfigurationScanner {
private String[] configFiles=null;
@Override
public String[] getConfigurations(Bundle bundle) {
String[] myConfigFiles=new String[configFiles.length];
for(int i=0;i<configFiles.length;i++){
String configFile=this.getConfigFiles()[i];
if(configFile.indexOf(":")==-1){
if(configFile.indexOf("/")!=0){
configFile="/"+configFile;
}
configFile="classpath:"+configFile;
}
myConfigFiles[i]=configFile;
}
this.setConfigFiles(myConfigFiles);
return myConfigFiles;
}
public String[] getConfigFiles() {
return configFiles;
}
public void setConfigFiles(String[] configFiles) {
this.configFiles = configFiles;
}
/**
*
*/
public ConfigableClassPathDefaultConfigurationScanner() {
// TODO Auto-generated constructor stub
}
public ConfigableClassPathDefaultConfigurationScanner(String[] configFiles) {
// TODO Auto-generated constructor stub
this.configFiles=configFiles;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
StandAloneOsgiBundleXmlApplicationContext
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.springframework.context.ApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
/**
* @author Edward Shen shendl_s@hotmail.com
*
*/
public class StandAloneOsgiBundleXmlApplicationContext extends
OsgiBundleXmlApplicationContext {
private String[] customConfigLocations=new String[]{};
@Override
public String[] getDefaultConfigLocations(){
return this.getCustomConfigLocations();
}
/**
*
*/
public StandAloneOsgiBundleXmlApplicationContext() {
// TODO Auto-generated constructor stub
}
/**
* @param parent
*/
public StandAloneOsgiBundleXmlApplicationContext(ApplicationContext parent) {
super(parent);
// TODO Auto-generated constructor stub
}
/**
* @param configLocations
*/
public StandAloneOsgiBundleXmlApplicationContext(String[] configLocations) {
super(configLocations);
this.setCustomConfigLocations(configLocations);
// TODO Auto-generated constructor stub
}
/**
* @param configLocations
* @param parent
*/
public StandAloneOsgiBundleXmlApplicationContext(String[] configLocations,
ApplicationContext parent) {
super(configLocations, parent);
this.setCustomConfigLocations(configLocations);
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public String[] getCustomConfigLocations() {
return customConfigLocations;
}
public void setCustomConfigLocations(String[] customConfigLocations) {
this.customConfigLocations = customConfigLocations;
}
}
StandAloneOsgiApplicationContextCreator
/**
*
*/
package net.sf.oxmled.springOsgiNoDM;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
import org.springframework.osgi.extender.OsgiApplicationContextCreator;
import org.springframework.osgi.extender.support.ApplicationContextConfiguration;
import org.springframework.osgi.extender.support.scanning.ConfigurationScanner;
import org.springframework.osgi.util.OsgiStringUtils;
import org.springframework.util.ObjectUtils;
/**
* @author shendl_s@hotmail.com
*
*/
public class StandAloneOsgiApplicationContextCreator implements
OsgiApplicationContextCreator {
/** logger */
private static final Log log = LogFactory.getLog(StandAloneOsgiApplicationContextCreator.class);
private boolean publishContextAsService=true;
private ConfigurationScanner configurationScanner ;
private String[] configFiles=null;
public String[] getConfigFiles() {
return configFiles;
}
public void setConfigFiles(String[] configFiles) {
this.configFiles = configFiles;
}
/**
*
*/
public StandAloneOsgiApplicationContextCreator() {
}
public StandAloneOsgiApplicationContextCreator(String[] configFiles) {
this.setConfigFiles(configFiles);
}
/* (non-Javadoc)
* @see org.springframework.osgi.extender.OsgiApplicationContextCreator#createApplicationContext(org.osgi.framework.BundleContext)
*/
public DelegatedExecutionOsgiBundleApplicationContext createApplicationContext(
BundleContext bundleContext) throws Exception {
// TODO Auto-generated method stub
Bundle bundle = bundleContext.getBundle();
this.configurationScanner=new ConfigableClassPathDefaultConfigurationScanner(configFiles);
ApplicationContextConfiguration config = new ApplicationContextConfiguration(bundle, configurationScanner);
if (log.isTraceEnabled())
log.trace("Created configuration " + config + " for bundle "
+ OsgiStringUtils.nullSafeNameAndSymName(bundle));
// it's not a spring bundle, ignore it
log.info("Discovered configurations " + ObjectUtils.nullSafeToString(config.getConfigurationLocations())
+ " in bundle [" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "]");
String[] strs=config.getConfigurationLocations();
DelegatedExecutionOsgiBundleApplicationContext sdoac = new OsgiBundleXmlApplicationContext(
config.getConfigurationLocations());
sdoac.setBundleContext(bundleContext);
sdoac.setPublishContextAsService(this.isPublishContextAsService());
sdoac.refresh();
return sdoac;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public boolean isPublishContextAsService() {
return publishContextAsService;
}
public void setPublishContextAsService(boolean publishContextAsService) {
this.publishContextAsService = publishContextAsService;
}
}
OSGI插件中创建ApplicationContext的演示
/**
*
*@author Edward Shen shendl_s@hotmail.com
*
*/
public class Activator implements BundleActivator {
private ClassLoader classLoader = this.getClass().getClassLoader();
private Log log = LogFactory.getLog(this.getClass());
private DelegatedExecutionOsgiBundleApplicationContext applicationContext;
public DelegatedExecutionOsgiBundleApplicationContext getApplicationContext() {
return applicationContext;
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) {
System.out.println("com.withub.gis.client.service Startup!!");
String[] configFiles = new String[] { "spring/bean.xml",
"/spring/client.xml", "classpath:spring/osgi.xml" };
StandAloneOsgiApplicationContextCreator standAloneOsgiApplicationContextCreator = new StandAloneOsgiApplicationContextCreator(
configFiles);
try {
this.applicationContext = standAloneOsgiApplicationContextCreator
.createApplicationContext(context);
applicationContext.refresh();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Spring ApplicationContext Startup!!");
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
System.out.println("com.withub.gis.client.service Shutdown!!");
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
}
解释
1.上面的演示代码中,我是用spring目录下的文件作为Spring的配置文件。
我不建议你在META-INF/spring/目录下编写spring配置文件。否则,如果你的插件的部署环境中有SPringDM存在,那么就会创建2个ApplicationContext。
2.现在,你的Spring配置文件中如果使用了Hibernate,也仍然是正确无误的!
目前,使用的spring配置文件不能使用Ant风格的通配符。如果有哪位朋友对Spring源代码有研究,希望能加上这个功能。我还有项目要完成,目前只能做到这个程度了。我的代码使用了SPringDM提供的API。这是一个简单的办法。因为Spring内部的源代码太多,太复杂了。我现在的这个办法是最简单的。由于我使用了SPringDM的代码,因此,你应该了解SPringDM的一些资源搜索的策略。
OSGi Search Strategy Prefix Explanation
Class Space classpath: Searches the bundle classloader (the bundle, all imported packages and required bundles). Forces the bundle to be resolved. This method has similar semantics to Bundle#getResource(String) Class Space classpath*: Searches the bundle classloader (the bundle and all imported packages and required bundles).Forces the bundle to be resolved.This method has similar semantics to Bundle#getResources(String) JAR File (or JarSpace) osgibundlejar: Searches only the bundle jar.Provides low-level access without Bundles and Application Contexts Spring Dynamic Modules(1.1.0) 8 OSGi Search Strategy Prefix Explanation requiring the bundle to be resolved. Bundle Space osgibundle: Searches the bundle jar and its attached fragments (if there are any). Does not create a class loader or force the bundle to be resolved.
如果提供的SPring资源没有前缀,我就会为你增加classpath:前缀。经过试验,只有classpath:前缀的资源才可以被正确导入。
如,下面的配置
<context:property-placeholder location=" spring/jdbc.properties"/>
在一般的Spring程序中是可用的。(当然,spring目录下有jdbc.properties这个文件)但是在OSGI环境下,就会报错,告诉我找不到spring/jdbc.properties这个资源。必须加上classpath:前缀,
<context:property-placeholder location="classpath:/spring/jdbc.properties"/>
现在就正确了!
发表评论
-
某osgi平台的uri
2012-06-19 19:06 01、http://localhost:9797/zcgl 2、 ... -
DWR与OSGi的整合
2011-12-30 21:56 1199DWR与OSGi的整合 最近一个项目中用了OSGi ... -
osgi常用链接
2011-12-30 21:54 9101、 http://dev.eclipse.org/viewc ... -
Extending Virgo with a HttpService
2011-12-30 21:52 1496Extending Virgo with a HttpServ ... -
jetty osgi 启动信息总结
2011-12-01 15:27 17491、运行java -jar -Dorg.osgi. ... -
OSGi Bundle的构建策略及实践
2011-11-23 21:12 1356OSGi Bundle的构建策略及 ... -
osgi 常用url
2011-11-12 17:15 9361、网络应用服务支撑运行平台 http://www.trust ... -
jetty in osgi ok
2011-11-02 18:04 11262011-11-2 17:29:13 org.springfr ... -
在spring osgi中取得datasource时出现问题
2011-11-02 15:06 1229在spring osgi中取得datasource时出现问题 ...
相关推荐
Spring OSGi是Spring框架与OSGi(Open Service Gateway Initiative)规范相结合的一种技术,它允许在OSGi容器中运行和管理Spring应用。OSGi是一种模块化系统,为Java应用程序提供了动态部署、版本控制和依赖管理的...
《OSGI实战:结合Spring DM》 OSGI(Open Service Gateway Initiative)是一种模块化系统和服务平台,它允许软件以模块化的方式进行构建、部署和管理。OSGI在Java世界中扮演着重要的角色,因为它提供了动态性、可...
在本文中,我们将深入探讨如何在OSGi环境中整合Spring-DM和Hibernate,以实现一个动态的、可扩展的持久化解决方案。Spring-DM(现在被称为Spring OSGi)是Spring框架在OSGi容器中的扩展,它允许我们充分利用OSGi的...
- **Spring DM**(Spring Dynamic Modules)是Spring框架的一个扩展,它结合了OSGi(Open Service Gateway Initiative)的强大功能,旨在帮助开发者在复杂的分布式环境中构建更加灵活、可扩展的应用程序。...
1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 ...
1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 ...
- **与Spring的集成**:Spring Dynamic Modules (Spring DM)是Spring框架与OSGi的桥梁,使得Spring应用可以在OSGi环境中运行。Spring DM允许在OSGi容器中管理Spring应用的bean和服务。 - **与Hibernate的集成**:在...
* Building modular services using OSGi with Spring DM and Spring Dynamic Modules and SpringSource dm Server. * Delivering web applications with Spring Web Flow, Spring MVC, Spring Portals, Struts, ...
1. 添加Spring DM支持库。 2. 配置Spring Bean。 3. 注册服务。 #### 十、OSGi与Hibernate框架的整合 OSGi也可以与Hibernate整合,实现持久层的管理和操作。 **步骤**: 1. 创建数据库表结构。 2. 定义Hibernate...
但是随后,Springsource决定退出他们的工作,并将其Spring DM Server解决方案提交给正在作为Eclipse Virgo运行的eclipse社区。 除此之外,还有很多声音(来自知名专家,但时刻关注着日期)不会鼓励您使用OSGi技术。...
**Spring Dynamic Modules (Spring DM)**是Spring的一个子项目,它将Spring框架与OSGi框架结合起来,使得Spring应用程序能够在OSGi环境下运行。Spring DM利用了Spring的IoC容器和OSGi的模块化能力,为开发者提供了一...
**Spring-DM**(Spring Dynamic Modules)是SpringSource推出的一个框架,它的目标是简化在OSGi环境中使用Spring的流程。它提供了一种方法来管理和部署Spring应用,使其能适应OSGi服务的生命周期。 **Maven**是一个...
可以查看博文链接(https://lyndon-lin.iteye.com/blog/856002)获取更详细的解决方案,或者参考Spring DM的官方文档以了解如何在OSGI中管理类加载。 总之,`NoClassDefFoundError`是一个典型的运行时异常,需要对...
3. SpringSource dm Server:这是一个开源的OSGi服务器,用于部署和管理基于Spring的应用程序。 针对企业集成,本书讲解了如何使用Spring Integration来进行服务集成,并介绍了消息传递模式。还探讨了Spring AMQP...
随着Spring的不断演进到3.0版本,它已经发展成为一个庞大的生态系统,SpringSource在其基础上创建了许多模块,这些模块不仅简化了Java EE的API,还提供了许多Java EE自身未涵盖的垂直解决方案,如应用集成、批处理和...
7. **CXF Example OSGi Blueprint** 和 **CXF Example OSGi**:这两个示例都是关于在OSGi环境中使用Camel-cxf组件,但分别使用OSGi Blueprint和Spring-DM来管理依赖。 8. **CXF Proxy Example**:演示了如何使用...
- **Spring 生态系统相关插件**: 包括 Spring Batch、Spring Data、Spring Security、Spring Web Services、Spring AOP 和 AspectJ 等插件。 **1.3 其他插件介绍** - **CoffeeScript**: 支持 CoffeeScript 编程...
- **OSGi**:为Java平台定义了一个动态模块系统,Equinox 和 SpringDM 是其中两个实现。 - **SOA框架**:如Apache Tuscany,用于构建服务导向架构(SOA)应用。 - **P3:特定领域框架** - **Flex/Sliverlight**:...