banq,关于第5章的框架,有几个问题,急。

我以前也做过类似的模块,基本上是参照PetStore的。拜读了 《Java实用系统开发指南》第5章,有几个问题不明白,请指教:
一.关于ComponentManager
1.ComponentManager及其实现类的作用和目的,原文说“可以实现有状态的行为”,我不太明白能否解释一下:如何做到上述目的?
2.属性ServiceLocator ls的作用?
3.getEJBController方法在哪里用到?
4.getSessionEJBsKey这个方法产生的Key,在一个session中为什么都是一样的?如果一个session保存多个EJBController怎么办?
5.每一个EJBController,无论是有状态还是无状态的,都需要保存吗?

二.关于EJBController
它的作用是什么?PetStore中EJBClientControllerEJB的作用是创建相应的FacadeBean和委托StateMachine执行Action。在您的框架中它的作用是什么?为什么在CustomerService类中直接把它转换成了FacadeBean?是否所有的FacadeBean都要继承EJBController?

就是这些了。

banq?

在线等...

不好意思,让你等了,sorry。

>1.ComponentManager及其实现类的作用和目的,原文说“可以实现有状态的行为”,我不太明白能否解释一下:如何做到上述目的?
主要他是HttpSessionListerner 可以自动激活,利用HttpSession保存有状态。

>2.属性ServiceLocator ls的作用?
就是PetStore中的ServiceLocator,是一种Service定位模式。

>3.getEJBController方法在哪里用到?
Web客户端需要调用EJB时用到,放在HttpSession作为缓存

>4.getSessionEJBsKey这个方法产生的Key,在一个session中为什么都是一样的?如果一个session保存多个EJBController怎么办?
key应该是EJB名称和SessionId的组合,保证唯一性,这里有性能缺陷,因此,采用EJB方法调用框架要好一些。

>5.每一个EJBController,无论是有状态还是无状态的,都需要保存吗?
有状态必须保存,无状态不要保存,保存也可以,可以提高性能,但是注意反复部署时问题,这个问题已经在JdonSD 2.0中克服,可以不断反复部署调试。

>二.关于EJBController它的作用是什么?
类似Petstore中的那个EJB总接口,学习他的。

>PetStore中EJBClientControllerEJB的作用是创建相应的FacadeBean和委托StateMachine执行Action。在您的框架中它的作用是什么?
我在以前帖子指出过Petstore这种调用EJB的命令模式有缺陷,这个我也在培训时向学生强调过。我的框架是继承他的优点,克服它的缺点,当然最后发现还是有其他缺点,如性能。

>为什么在CustomerService类中直接把它转换成了FacadeBean?是否所有的FacadeBean都要继承EJBController?

是的,CustomerService是EJBController的客户端。所有要直接面向客户端的EJB都要继承EJBController

总的来说,这个框架只是试图向大家介绍如何做框架,作为设计框架的起步,这也是我培训的一个示例,实际成熟使用性不强。


谢谢回答,明白了。一句话就是提供了设计的思路,而不提供具体的实现。好吧,那么我自己参考这个作一个类似的模块(我不喜欢称之为框架)好了。
另外还有一个问题,书中说PetStore中的做法会导致“粗糙的的事务处理”,我在其他参考资料(EJB design patterns)中也见到了类似的说法,请问您的框架中是如何解决这个问题的?

书中提供了实现的主要部分代码,当然不是全部代码。:)

目前JdonSD框架基于动态代理和Picocontainer实现的一个框架,之所以称框架,而不是模块,因为框架需要继承和实现的,而模块可能本身就是一些实在的功能,我个人认为EJB组件称为模块比较合适。呵呵,随便谈谈,不是为了争论。


>PetStore中的做法会导致“粗糙的的事务处理”,
这个我在EJB调用模式文章中也说了:
http://www.jdon.com/jive/article.jsp?forum=91&thread=12347
主要它的command类是一个普通的JavaBeans,而不是EJB,是在JavaBeans的方法中再调用其他EJB,这个JavaBeans方法内部无法实施事务了。就如同在Web层的JavaBeans中调用两个EJB,如果后一个EJB出错,前一个EJB不会回滚。

谢谢banq的回答。
是否可以这样认为,EJBController作为总的FacadeBean,在其中调用其他的FacadeBean实现商业逻辑,从而充分利用容器对于事务的支持。
EJBController在某种意义上讲也是一种Command的实现,和ServiceProxy一样,前者在EJB容器中,后者在Web容器。ServicProxy只需调用一个EJBController就可以了,被调用的EJBController再使用其他的FacadeBean(1...*)。从而使得整个框架做到了Web层和EJB层的桥梁。

我使用Stateful Session bean的时候很少,所以还是不太明白ComponentManager的作用。难道Stateful Session bean只有保存在HttpSession中才能实现状态吗?那么如果通过其他客户端(比如Corba)调用Stateful Session bean怎么办?再有,如果有状态SessionBean保存在HttpSession中,那么钝化和激活机制还起作用吗?我以前理解的Stateful Session bean是:本身相当于HttpSession,不同的是它带有方法(Session Java Bean?),而且可以利用容器提供的种种机制。不知是否有误?

你对EJBController认识非常正确,是这个意思,在实际过程中,让facadeEJB再去继承一个接口,比较累,这就是EJB的一个缺点了,到了EJB 3.0,就方便多了。

Stateful Session的引用一定要保存在客户端内存中,以便客户端下次再使用这个Stateful Session,Stateful Session就是一种缓存数据,我已经反复在教材中说了,无态EJB是Pool,而Stateful Session是Cache,如果深刻掌握Pool和Cache的区别,那么EJB Session Bean就掌握,我这个教学思路和那些《精通EJB 》之类或SUN培训教程不一样,但是我认为这对于初学者容易突破,而且可以触类旁通,从而认识使用EJB的本质,实际在使用Pool和Cache(可以跨服务器的),如果你不喜欢EJB,但是Pool和Cache是每个成熟系统不能逃避的,所以可以使用Javabean自己做,Spring之类的框架发展下去也要加入这个两个东西。

Stateful Session是Cache,Cache是针对同一个客户端的,所以要保证每次客户端访问服务器时,访问的是同一个内存块,那么当然要将这个内存块的引用地址给下一次request使用。

你理解的Stateful Session是对的,使用时需要按照上面那样做,现在外面的EJB书籍实际过于复杂,学EJB其实重在应用就可以。

倒!
我试了一下,有状态EJB不但要保存在session中而且不能调用remove。以前都是用无状态EJB,从来没有用过有状态的。一向是用什么学什么,汗...

谢谢banq,我明白了,ComponentManager不但将bean保存在session中,而且可以及时remove。

>可以及时remove
这个很重要,需要人工remove,当然容器自己也可以remove,可是太累了容器,会降低性能,可见EJB使用有很多误区。需要有人引导。

ComponentManager可以自动做这个工作,这个思想其实来自Petstore,我当初接受这个概念,也是象你今天如此的惊叹了。

有人可能抱怨我一些帖子讲得不够明白,那要看对方交流的对象,这个帖子我觉得我讲得很透彻,因为有cats_tiger 这样的交流者。

希望有多多cats_tiger 这样善于思考、冷静的交流者,我也会从中体会到交流的乐趣,这个网站就是这个目的的。


>ComponentManager可以自动做这个工作,这个思想其实来自Petstore
惭愧,一直以为看明白了PetStore,原来还差的远。
好了,这次的讨论我弄懂了,下次可能就“EJB方法调用”一章提一些问题,望banq大哥继续支持。谢了!

BANQ的意思是把SFSB放在HTTPSESSION中,然后在HttpSessionListener中removeSFSB.

关于前面提到petstore实现Command模式调用EJB的粗粒度事务,在spring+ ejb中也存在,在spring手册中,他推荐使用EJB,可继承他的AbstractStatelssEJBXXX,然后将SLSB中方法全部委托给POJO做,例如:

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

service的方法:
public void updateUser(){
updateTabel1();
updateTable2();
}

当updateTable2()抛出异常,updateTable1()是不回滚的。
而只有这么做,才全部回滚:
ejb方法:
public void updateUser(){
updateTabel1();
updateTable2();
}

如果service的方法updateTabel1();与updateTable2(); 都是调用CMP也不能回滚吗?您说的不能回滚是指通过什么方法操作数据库呢?请指教,谢谢!