发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 大数据 扩展性 并发编程 事件驱动 分布式 SOA
1 2 3 4 ... 8 下一页 Go 8

转贴:Spring vs. EJB

              
2005-02-03 20:59
赞助商链接

引自:http://www.cnblogs.com/raimundo/archive/2004/09/20/44697.html

我知道我要挨扳砖,没事,来吧:)

赫赫,我来说一下spring vs EJB,首先强调,我不是ejb的拥护者,但我欣赏他的完整、他的学院气,同时也深感他的硬伤,我不是spring的拥护者,虽然去年3、4月间看

到spring的时候曾经让我眼前一亮。对ejb有太多的误解,对spring有太多的吹捧,我希望这是一个相对公平的比较.

我认为spring和ejb的差异在这样三个方面,一个是受众也就是这两个叫framework也好叫platform也好的东西的scope;另一个是component architecture,最后一个是语义



1.Scope比较

先说scope,ejb的scope是什么?ejb针对什么系统来设计的?这个我想一个人一个答案,我说了不算,同样大家说了也不算,我们来看规范(题外说一句,我想本来我没啥

资格在这里谈论ejb,我应用ejb的项目不多,但是我有个习惯,就是读规范学技术,不管别人怎么说先看这个东西是怎么来的,我想这一点还使我有些开口的自信,不至于太

贻笑大方),ejb规范的头几句:
Enterprise JavaBeans is an architecture for component-based computing.Enterprise beans are components of transaction-oriented enterprise

applications.


好了,很明确,ejb是针对transaction-oriented enterprise application的组件,那么也就使说ejb是面向以事务为中心的企业软件,而不是别的。ejb的核心是

transaction,不是domain model或别的。
why transaction?我在电力行业做过一阵信息化软件架构师,在电力这样一个需要处理大量数据的领域里,很少有oo model,而是做完entity分析,交给dba去优化,以数据

性能为主,这样的系统里,数据操作的粒度就是transaction,而不是object或是别的。我想这该算是一个大型企业级系统,我看到的是transaction,因此ejb这个把scope定

在enterprise级的东西而言,这样的设计还使合理。而且ejb对transaction这部分的处理确实比较完整,cmt,bmt,不同的transaction scope控制的都很好。基于这种认识,

我认识transaction script是ejb的标准应用模式,而不是domain model或是别的。
这是对ejb最大的误解的来源,我看过的所有ejb书里,只有o'reilly的一本隐约提到transaction是ejb的中心。其他一律不提,疯狂的鼓吹ejb多好多好ejb多么万能,我想

,如果不知道ejb是transaction-oriented的,那么ejb奇怪的对象模型的确不可接受。

再说spring,spring是什么呢?我没有看到特别明确的定义,不过我想仿照ejb,定义spring为:
Spring is a Javabean-based framework that supporting component architecture development.Spring provides lighter context for heterogeneous entrprise

application.

我e文很差,cet-6 6次都没过,我想说明的是,spring是一个轻量化的组件架构,可以支持多种企业应用程序模式.看到这里有人又该说了,no,no还有ioc,还有aop,没错这

些很cool的特性我没说,但是包含了,component architecture意味着两个方面,component working(编写组件)和container working(编写容器环境),spring的ioc和aop是

用在container working里的.当然肯定还有其他的一些没有概括,但是我想主体我还是说到了的.这样scope就很明确了,spring的基础是javaBean,javaBean支持完整的oo建

模,因此spring可以适用更多的结构,domain model和别的一些。

那么开始比较,spring有一个理论上普适的组件模型,但是鉴于大型应用多为transaction-oriented,那么用spring的理由就是domain model,ejb不能提供完整的oo模型而

spring可以。

结论:由于scope不同,其实比较spring和ejb那个更适合企业开发没什么意义,因为这里面根本就是两个不同的范畴,在scope上指责ejb不如spring,就好像说raimundox,你

就不能替老婆把孩子生了,还让她那么痛苦的怀胎十月。其实我也不想,我也想替,可惜我们这功能.....扯远了,ejb也是,没这功能你怎么强求他呢?你要说ejb设计的不好

,也不对,人家有专门的领域。因此我说,在scope上比较spring和ejb没意义,根本不是一个级别的。

2.component architecture

Component architecture有一个基本观点,就是component和context的分离,理想情况下,component只负责业务的实现,而container提供context,这个context只技术

context,比如事务比如安全的支持。于是,component architecture的基本观点就是business关注点和technique关注点分离,business由component负责,technique由

context或者叫container实现。那么很明确了,component architecture里有两种编程,针对component的和针对container的。
好,有了这个理解,我们可以继续了,如果有人有疑意,那么抱歉,这片文章并不适合您,后面全部的论点都是基于这个观点的,如果不认可这个,下面的也不会认可,您

也不用浪费时间了。

首先看ejb的component方面,ejb在component architecute做得非常的好,ejb就是一个业务组件,在container-managed的情况下,组件通过声明可以应用容器提供的技术

context,当container-managed不满需要的情况下,可以bean-managed,只要保持对外的事务语义就可以了(记得吗?ejb是transaction-oriented,事务最重要)。在ejb里

,组件和容器的约定非常明确,哪些需要组件写,哪些是容器提供的非常明确,这是component architecture里很好的习惯,明确组件和容器的界限(ejb的一个缺点,矫枉过

正,有一些操作也被禁止)。编写代码非常容易,业务,only业务。其实ejb的规范里,ejb的coder其实最好是domain expert,实现业务逻辑就好了。

现在来看spring的component方面,spring以javaBean为基础,贫容器,也就是对容器没要求,于是,spring第一个缺点,contianer和component的约定不清晰(写到这里我

已经听到一些人在叫了,这是spring的优点,自由,别急,后面我会证明这是spring的软肋),但是spring用了一种比较聪明的办法,那就是加强container working.

看一下spring的container working,通过spring的aop api,我们可以很容易的为特定组件定制容器环境,把一个组件需要的容器技术环境以aspect的形式weave到component

里,非常的灵活,也非常的强大,spring通过这种形式来弥补组件/容器约定不足的情况,一切由component选择,容器除了装配(ioc/dip)不提供任何技术context,想要什

么自己来,这个给了component实现者自己选择的权利,很好(但也隐含了spring的最大的不足,别急我后面会说)。

再来看ejb,非常遗憾,ejb container working的能力几乎为0,当然算上jca的话还不算太差,但是那只是资源,而不是技术context。why?因为ejb认为他已经提供了所有

企业级开发所必需的技术context了,事务(ejb里我总把他放在第一位)、分布、并发、安全等等。在ejb看来container working的能力几乎无用,而且不安全,除了jboss开放

了比较多的container working接口其他的ejb container提供这方面的支持很少很少.当然提供很多技术context并不是坏事,要命的是不能配置,要么全用要么不用(倒是很

原子),这是ejb最大的不足,容器环境不可配,也是spring强于ejb的地方。

上面我们已经看到了spring和ejb都是component architecture,那么component能想到的最直接的用处就是复用。那么比较这一点就是比较ejb和spring component

architecture的关键。看到这里spring的支持者们该常出一口气了,spring复用一定强于ejb复用,赫赫,但我的结论正好相反,ejb复用优于spring复用!!收起你们的愤怒

,收起你们不屑,听我把话说完。

在component architecture里,component是业务实现,而不该有技术代码,就算用也要通过容器环境去和容器交互来完成操作,比如ServletContext等东西。那么其实

组建结构下复用的关键不是组建而是容器!!


以前有一个颇有名气的dx(gigix别看了,说你呢),说"COM和EJB都鼓吹模块化和复用,模块化是真的,复用是骗人的",com我不是很熟,不好下结论,ejb呢?ejb不易复用我

承认,但是骗人吗?不骗,后面我给出一种ejb复用的思路大家参考。反正组件一点技术都不作,只有业务逻辑想用就要有相应的容器环境,那么容器环境的复用性才是组件复

用的关键。ejb不易复用是因为如果脱离容器,我们就必须给它提供相应的技术context,事务、分布、并发等等一个也不能少,因此容器外复用ejb效率很低。注意,

是容器外,组件本来就是跑在容器里的,谁让你非要拿出去用),而容器内呢?因为ejb规范规定ejb容器应该兼容,别说webSphere到bea的移植有多难,其实不难,或

者说难度比把spring组件移植到pico复杂一点,当然你用vendor-specified的特性就没办法了,这不再规范内,你违规就别怨人家。因此,ejb的复用是可以的,而且是规范保

证的,容器外也有办法,也不是很难,我后面说。

再看spring,的确他很灵活,但这正是致命伤,component完全是业务实现,但是容器呢?spring怎么保证容器的环境?没有,只能你自己保证,当你沾沾自喜的说,spring

里的component都是pojo,可以很好复用的时候,可曾想到,这复用的代价是要复用容器。比如有个componentA,在SystemA里需要事务模型A和安全模型A,在SystemB里需要事

务模型B和安全模型B,当你从SystemA里复用componentA的时候,你要怎样?重写事务模型B和安全模型B,然后你可以堂而皇之的说,你复用了组件。的确,你复用了组件,但

是你重写了容器,值吗?更可怕的是,spring容器和组件没有约定,那么怎么保证你的组建不写技术代码?ejb只要Bean-Managed并提供统一的事务模型就好了,spring呢?你

靠什么保证?你自己?这是spring一大硬伤,完全container-managed下缺少特定的component边界控制.你可以说,特殊要求的事务模型ejb还实现不了呢,的确,这是有可能

,但是ejb transaction model不能适用的情况有多少?如果真的不行,只能说ejb的简单复用在这里失效。

对于组件还有一个问题就是部署,这也是ejb为人诟病的地方.的确,ejb的部署够复杂,但在ejb规范里有一个专门的角色来负责部署的,ejb是component architecture,那

么比如有一个人来粘合技术和业务,这个人不该是programmer(我刚才说了,ejb的实现者最好是业务专家,实现业务逻辑),ejb的部署才是很厉害的人,他需要知道什么业务

需要什么样的技术支持,该怎样得到性能,因此deployer才是ejb architecture里最牛的,我重来不以为写ejb的是高手,但是一直都敬仰ejb的deployer.当然这里有一个调试

困难的问题,这是ejb的硬伤,没办法,这甚至是组件开发的硬伤.
再来看spring,spring宣称他部署简单,我觉得rod johnson在转移视线,想想看,打成一个war和打成一个ear有多大的区别?那么部署的差异在哪?差异在ejb的deploy

description和spring的context.xml的编写上!在用spring开发中要有一个人来写context.xml这个人往往比较了解系统,知道什么组件用什么拦截,那个组件依赖那个,甚至

会是架构师在作这件事情,那么和ejb里对系统有大局观的人来做deploy有多大区别?可能就是Xml的编写吧,我想在工具的支持下就是熟练度的问题,因此我觉得部署上

spring和ejb差不多,spring不用启server,调试放便些。

结论,在component architecture上,spring灵活,ejb统一完整,各胜擅长,spring的灵活以降低复用为代价,但是如果有common的技术实现,的确很好复用,但是

spring+一套common的技术实现也就约等于ejb了吧?

3.语义

那么spring复用的问题表明了什么呢?其实是缺乏语义的支持,ejb开发可以看作在一个统一的语义环境下来作的,这个语义由ejb规范规定,因此ejb的复用有语义保证,而

spring呢?贫语义,一切都要开发者自己来实现。因此,如果ejb的环境语义可扩展并且可配置(比如去掉分布),那么spring毫无优势,标准的一致的完整的组件架构使ejb

会大有作为,但是现在并没有,才有了spring的火爆.这是一种畸形的胜利,完备语义的输给了贫语义的,问题是什么,强迫消费...谁让ejb非得强迫客户去买用不到的分布式

环境的单?但是统一语义的威力不会因此掩灭,现在有两条路,spring联合os社区,制定lightweight j2ee语义集合,争取成为标准。第二,ejb实现技术语义可配置可扩展。

谁会胜利?不好说,但是似乎ejb的脚步快一些!

附:容器外复用ejb

其实ejb在容器外完全是可以用的,但是为了最大限度保证能用,bean-managed是推荐(不是cmp,bmp而是cmt,bmt),那么怎么传送一个transaction进去?SessionContext(

好像是这名记不清了,都快2:00了,困呀...就是ejb那个context接口),一个接口嘛,自己mock一下,给一个transaction进去就好了。怎么装配?spring的setter

injection。如果用spring,那么cmt也可以实现,拦截啦,不过就看能不能实现ejb transaction model了。entity bean,如果是bmp,就用它好了,cmp,继承一个上

hibernate。这些都模拟好了,找一个in memory的jndi,把spring context封进去,这样相当于我们用spring实现了一个lightweight ejb container(其实就是给spring一个

ejb api的皮),轻到什么程度?除了注射什么都没有。
然后client就可以构造jndi,然后lookup了
看到这里一定有人说,你吃饱了撑的,这么费劲容器外复用ejb,为什么不直接用spring,这样也不够pojo,每个组件都有ejb的类的继承,好,我告诉你这么做的好处,首先

,虽然不够pojo,但是足够bean,因此spring来管理ejb是可以的,证明我的观点容器外使用ejb可以(赫赫,不要说偶rpwt...).其次的,当业务发展了,你的系统需要分布了

,把spring去掉,拿出ejb,redeploy,ok了,延展,稳定,分布都有了,这才是复用该有的境界,改一个部署整个环境换掉,去掉lightweight的ejb container,换乘

heavyweight的就是重量级。
当然这么实现很难,在ejb3里会容易些,我敢打赌,spring以后一定是lightweight ejb container的供应商,免不免费,os不os要看rod johnson了,不过我觉得希望不大。

致谢:

首先感谢dlee,在和他的讨论中形成了这篇文章的主题,然后是冰云,他帮我审稿直到2:04,udoo,perhaps都提出了中肯的意见,谢谢他们.

当然也欢迎大家访问我的blog:www.cnblogs.com/raimundo

2005-02-03 21:00

觉得比较有意思,贴出来与大家一起共享和探讨。

myy
2005-02-03 21:58

那么其实组件结构下复用的关键不是组件而是容器!!

--------------------------------------------
我是java菜鸟一个,不过上面的这句话很赞同!

道理很简单,就象Delphi的vcl控件一样,在delphi程序和BCB程序
中复用性是大大的好,但绝对不能直接拿到VC,VB中去用。

2005-02-04 18:57

这是一篇非常有专业水准的、来自实践原创的文章,2004年的Java世界中是一个喧闹、甚至有些偏执的世界。

这篇文章从另外一种角度说出了我心里一直想说的,可惜我一直没有时间,大家可以从我以前文章星星点点中看出与本文的一致意见。

>在scope上比较spring和ejb没意义,根本不是一个级别的
我看到这篇文章的题目 Spring vs EJB, 我立即想,这本不可以比较,又有人来比较,搞些噱头,现在仔细看看,才发现我误解了。

有些人信誓旦旦说:POJO必胜, POJO是什么?普通JavaBeans啊,EJB的名词怎么写?Enterprise JavaBeans, J2EE历史上,先有JavaBeans;后有Enterprise JavaBeans;你现在说POJO必胜,是不是很奇怪、无知的信念?或者说毫无意义的概念,是正确的废话。

哗众取宠的人借用Spring打出Without EJB的口号,非常令我恶心。

>spring第一个缺点,contianer和component的约定不清晰
我以前的帖子说了,使用Spring后,相当于什么都没使用,"Spring宣称它自己侵入性很少,所以,用反义词来说:就是它什么都不做,或者说,它没有什么东西,只有Ioc/AOP模式。"

所以使用Spring的人,你以后就象自己做数据库连接池吃苦去吧,项目失败或被炒鱿鱼被怨恨Java身上。
当然,高手除外,可惜如果我也算高手的话,我宁愿自己做一个框架更顺手,如JdonFramework,这样以后在我架构设计下的业务逻辑都只和我的框架耦合,我复杂跟随技术发展升级我的框架即可,我的业务组件得到了保护和延长了生命,只有傻瓜高手才会基于Spring这样非业界标准将自己的鸡蛋都放在其中,因为老板外行不知,如果来看了Jdon网站,非不把他炒鱿鱼!

>有了spring的火爆.这是一种畸形的胜利
我早就抨击这些虚伪、畸形的热闹,因为这,我竟然被人从"程序员"专题撰稿人的位置上踢出来,可见,要让大家明白争相是多么难的事情。

所幸,技术的真相比社会的真相更容易 更快让人明白,所以我爱技术。

>EJB可以复用
我早说过EJB可以复用,否则就没有SOA赖以生存的基础,JdonSD构件库基本都是EJB组件。

EJB的优点主要是其标准,标准是人定的,因此EJB是有生命的,可以更改的,技术发展了,加入新技术,就这样简单,,,,EJB其它缺点都是技术的缺点,不是EJB缺点,技术是发展的,可以更新的。

那些说EJB这个问题、那个问题的人注意了,这个基本概念都搞不清楚,最好不要搞Java。M$东西很好啊。


2005-02-05 11:07

俗话说得好啊!

无知者无畏!

写出这篇文章的人已经被EJB 骗的七荤八素滴了!!

我也懒得再花精力跟他一一辩驳了,我只列出一些几百年前就已经被别人讨论过的观点再罗列一下:
EJB所谓的分布式事务支持是建立在JTA规范之上,和EJB本身没有任何关系,只不过它弄了一个恶心的deployment descriptor来做配置。

说spring不支持分布式事务的人更是胡说八道,去好好看看spring的代码,PlatformTransactionManager隔离了JTA Transaction Manager和Local Transaction Manager的不同,让你方便地切换事务管理(Local/Distributed ),而不用去修改代码。

结论就是:
在java里面,分布式企业应用不能without JTA,而恶心的EJB只是挂JTA的羊头来卖狗肉,骗骗那些不懂事的小孩子......

反驳:
开发一个企业级的分布式的应用,当然那了,既然是企业级的,就要兼顾很多问题了,事务,并发,安全,缓存... 当然RMI,和webservice都可以实现,但是却具备不了企业级应用必须的东西,如果单单是为了实现分布式,那我上面列举Hessian, Burlap,XmlRpc......
这些东西都可以实现,但是如何兼顾事务,并发,安全,缓存...这才是我们必须考虑的问题,而EJB恰好解决了这个问题,现在就是如何在非EJB环境下解决这些问题。

辩驳:
如果不考虑业务对象分布的话,EJB容器无非两件事:组件生命周期管理,infrastructure管理。第一件事我们用轻量级IoC容器实现,第二件事我们用AOP实现。这需要在搭建template application时做较多的工作,收益则是有更多的选择,而不是全盘接受所有的infrastructures。对于普通程序员,唯一的变化就是他们编写的组件是POJO,而不是EJB。



辩驳:
那个容器可以设置远程 对象的实例化个数呢???

com+可以 ,ejb容器可以。

spring好像只有“预创建单件模式”吧?

scalable 的软件,不想被无限的client拖垮,必须考虑这个 问题

反驳:
那个容器可以设置远程 对象的实例化个数呢???

com+可以 ,ejb容器可以。

spring好像只有“预创建单件模式”吧?

scalable 的软件,不想被无限的client拖垮,必须考虑这个 问题

辩驳:
先去弄清楚状况,偶们前面讨论的是分布式事务。

不想被无限的client拖垮,只能用集群。
集群和分布式事务是没有关系的。

另外,集群和spring也是没有多大关系的,无论你用什么技术,只要解决各个节点上有状态对象的复制,就能做集群。

It really comes down to where you want to do your load balancing.

You could write a Java-based distributor to do it, maintaining a list of target beans on different servers and their current load, bouncing long-running requests through to each.

Or you could use a load balancer (as Olivier suggested) which does the same thing, but instead of at a Java level it works at the HTTP level. Load balancers can distribute traffic in various configuration patterns based on round-robbin and even based on individual server load. They tend to offer quite sophisticated options as well, such as the target server being able to work at the MAC address level and respond directly to the client rather than directing the response back through the load balancer. Load balancers are a mature technology backed by a lot of R&D and real-world deployments. To give you some idea, see "Three Ways to Load Balance" at http://www.linux-mag.com/2003-11/clusters_01.html.

The nice thing about a dedicated load balancer is you don't have to write it. A Java-based distributor will be time-consuming as you need to poll target beans (to determine their present load/availability) or otherwise track the volume of outstanding requests for each target bean. For all the effort, it will probably be comparatively inefficient unless you spend lots of engineering time. It really isn't the sort of thing you want to be developing if a standard load balancer will meet your needs. Of course many application servers will load balance for you, but then you're adding a layer of software and typically RMI which would probably still not be as efficient as the web services clients being directed by a proper load balancer at a nice low OSI layer to an available web container.


oliverhutchison:
引用:
Another option would be to look at writing your "job" processing system using a message driven approach. ActiveMQ has recently added support for message driven POJOs which could be exactly what you're after. See: http://sourceforge.net/mailarchive/message.php?msg_id=9896311. A great thing about JMS is that if you don’t need a distributed system you can run the message producers/consumers all "in process" with very little overhead but if/when you do need to add servers you are insulated from a lot of the mechanics of this process.

You're spoilt for choice on this one, but don't forget, (as Ben often says;)) KISS (keep it simple stupid), before you start creating a super distributed architecture with all the bells and whistles it's worth spending a bit of time to analyze whether this is really something you need.
Ollie

8Go 1 2 3 4 ... 8 下一页

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系管理员 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com