首    页 建模架构 设计模式 培训咨询 jdon框架 论坛

  探讨Spring框架使用真相

板桥里人 http://www.jdon.com 2004/08/25

  最近,Spring很热闹,因为实现IoC模式和AOP(见本站专栏),然后又成立公司,吸取上次JBoss的教训,文档不敢收费,结果迎来了一片祝贺声。

  Spring真正的精华是它的Ioc模式实现的BeanFactory和AOP,它自己在这个基础上延伸的功能有些画蛇添足。

  其实说白了,大家"惊奇"的是它的IoC模式(使用AOP功能需要了解AOP,比较难),那么,Spring之类的Ioc模式是什么? 就是:你在编制程序时,只要写被调用者的接口代码,具体子类实例可通过配置实现。

  Ioc模式是什么知道的人不多,但是,当他知道生成对象不用再使用new了,只要在配置文件里配置一下,他感到新鲜,其实这就是Ioc模式的实现,PicoContainer是另外一种真正轻量的Ioc模式实现,PicoContainer还是采取代码将对象注射一个小容器中,而Spring采取配置文件。

  配置式编码其实有利有弊,编码本来可通过开发工具或编译器检查错误,但是过分依赖配置时,就会经常出现因为粗心导致的小错误,如果调试程序出错经常是因为配置文件中小写字母写成大写字母,不知道你是怎么心情?

  Spring最近还发表了Spring without EJB的书,这倒是说了实话,Spring和EJB其实是相竞争,如同黑与白,如果硬是将两者搭配使用,显得不协调,更不是一些人所谓优化EJB调用的谣言,原因下面将会分析。既然Spring+EJB有缺陷,那么就直接使用Spring+Hibernate架构,但是又带来了新问题:无集群分布式计算性能,只能在一台机器上运行啊,具体分析见:可伸缩性和重/轻量,谁是实用系统的架构主选?

  下面来分析所谓Spring+EJB的不协调性,正如水和油搅拌在一起使用一样。
  目前,Spring+EJB有两种应用方式:

  1. Spring不介入EJB容器,只做Web与EJB之间的接口,这个位置比较尴尬,Web层直接调用EJB的方法比较直接快捷,为什么要中间加个Spring?可实现Web缓存?使用性能更好的AOP框架aspectwerkz啊;实现Web和EJB解耦?这样的工具更多,自己都可以做个小框架实现,就不必打扰背着AOP和IOC双重重担的Spring了吧。

  2. Spring介入EJB容器,这时,需要在你的ejb-jar.xml中配置beanFactoryPath值指向你为EJB配置的applicationContext.xml,那么你的EJB还需要继承Spring的SimpleRemoteStatelessSessionProxyFactoryBean。

  好了,现在你的SLSB(无状态Session Bean)成为下面这个样子:

  void updateUser(){
    
      myService.updateUser(); //委托给一个POJO的方法,真正业务逻辑封装在这个POJO中

  }

  这样做有很多“优点”,当然最大“优点”是:

  由于真正业务核心在POJO中实现,因此,只要改一下applicationContext.xml配置,这样,调试时,前台就可以直接调用POJO,不必通过EJB,调试起来方便了,这有一个前提:他们认为调试EJB复杂,其实不然,在JBuilder中,结合Junit,测试EJB如同测试POJO一样方便,这是其他分支,不在此讨论。当部署使用时,再改一下applicationContext.xml配置,指引前台调用到EJB。

  似乎很巧妙,这里有两个疑问,首先,指引到EJB的改变是什么时候做?持续集成前还是后,在前在后都有问题,这里不仔细分析。

  这种表面巧妙的优点带来最大的问题是:粗粒度事务机制。所谓粗粒度事务机制,最早见于Petstore的WEB调用EJB Command模式,在这个帖子中有讨论。

  下面以代码描述什么是粗粒度事务机制:

  ejb方法:
  public void updateUser(){
    service.updateUser();
  }

  service是一个POJO,具体方法可能是更新两个表:
  public void updateUser(){
    updateTabel1();//更新table1
    updateTable2(); //更新table2
  }

  当updateTable2()抛出异常,updateTable1()是不回滚的。这样,table1中就有一条错误的多余的记录,而table2则没有这条记录。

  那么,怎么做才能使两个表记录一致,采取事务机制,只有下面这样书写才能实现真正事务:
在EJB方法中写两个方法,因为EJB方法体缺省是一个事务。
  public void updateUser(){
    updateTabel1();//更新table1
    updateTable2(); //更新table2
  }

  关于EJB自动的事务机制,最近也有一个道友做了测试,对于JBoss中容器管理的事务的疑惑。

  如果你从事关键事务,就是带money相关操作的事务,这种粗粒度机制可能害苦你,那么,似乎有一种办法可弥补事务,不使用EJB容器事务(CMT),在service中使用Spring的事务机制。

  如果使用Spring事务机制,业务核心又在POJO中实现,那么我有一个疑问:还要套上EJB干什么?至此,你终于明白,Spring本质是和EJB竞争的,如果硬套上EJB使用,只是相借助其集群分布式功能,而这个正是Spring目前所缺少的。

  我太惊异Spring精巧的诡异了,他和EJB关系,正如异型和人的关系一样。

  为了避免你每次使用Spring时想到粘糊糊的异型,不如Spring without EJB,这也正是Spring的初衷,也是它的一个畅销书名。

  为让初学者更容易掌握Spring,在本站教学区新增一篇“Spring入门速成”,简单易懂,专门针对VIP会员的。

参考文章:

Spring专题

Spring 和EJB终于统一融合

国人最早开源IOC/AOP框架JdonFramework

AOP权限拦截器在JiveJdon中应用源码

Ioc模式(又称DI:Dependency Injection)

IOC模式的思考和疑问

Ioc容器的革命性优点

Java企业系统架构选择考量

JBoss 5迎来Java的彻底的可配置时代

Jive论坛与Spring框架


发表讨论..

 

更多依赖注射专题

更多AOP专题

更多关于IOC讨论

更多关于AOP讨论

更多关于Spring讨论

 


更多标签...



Jdon框架演示

JiveJdon
源码下载

VIP收费区

历史热点讨论排行榜




google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘





手机 add to google add to yahoo
联系我们 | 关于我们 | 广告联系 | 网站地图 | 设为首页

沪ICP证08026060 如有意见请与我们联系 Powered by JdonFramework
_×
您有新消息