OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]

http://code.google.com/p/springosginodm/

 

OSGI+Spring+Hibernate+...完美解决方案[非SpringDM]

导论 “世间本无事,庸人自扰之” SpringDM就是一庸人!

最近,我做一个项目需要编写 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状态的插件。 1)MANIFEST.MF中没有Spring的头,如果有,执行该配置。 2)如果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的方法。

你可能感兴趣的:(eclipse,spring,Hibernate,配置管理,osgi)