<尚学堂><EJB> 2-EJB3.0简介、有状态和无状态的Session Bean
1.EJB3.0技术简介:
1> 被简化的EJB API:
EJB3.0消除了对Home接口的依赖, 所有持久化对象不必再实现任何EJB API接口.
Session Bean, Message Driven Bean, Entity Bean现在只是简单的 Java Bean.
2> Java Annotations:
EJB3.0需要用到JDK5.0出现的新特性:Annotations。 Annotation特性使发布描述文件变成一个可选项, 而非必须项。EJB3.0定义了很多的Annotation,覆盖了众多与持久化相关的概念。比如:Bean的类型、依赖注入、事务管理、安全、回调、O/R Mapping、关系等等。如果你想要覆盖在Annotations中的定义,那么发布描述文件依然有他的用武之地。JBoss应用服务器和Hibernate都支持这些Annotation,这就意味着,如果你使用HIbernate的话, 你可以在EJB3.0容器之外和在单独的Java应用程序中获得EJB3.0Annotation所带来的一切好处。
3> 依赖注入(DI):
通过定义@Inject、 @EJB、 @Resouce等Annotations,这些依赖关系现在可以由容器来注入到EJB中。
4> 可选的回调机制:
开发者们现在可以仅仅实现他们感兴趣的那些回调方法了。 通过定义@PostConstruct、 @PreDestroy、 @PrePersist,开发者们可以映射任何Java Bean或者回调类的方法, 让它们接受这些时间。
5> Entity Manager API:
一个普通的Java Bean实例, 可以通过EntityManager API来持久化到数据库中, 当然也可以从EntityManager中获取一个Java Bean实例,修改之后, 再次持久化到数据库中。JBoss应用服务器和Hibernate都支持这个新的API。
6> 简化的持久化模型和改良的查询:
EJB 3.0 将Java持久化模型进行标准化,Hibernate扮演了至关重要的角色, 一套完整的Java Annotations被用来定义处理O/R Mapping和不同的对象关系。EJB3.0也增强了EJB-QL查询语言。 支持动态查询、子查询、批量更新、批量删除等。
7> 可以脱离容器的使用:
EJB 3.0 规范允许你在普通的Java应用程序中使用它的持久化API。
什么情况下需要企业Bean! 【二-13:00】
企业Bean运行在EJB容器中.企业Bean实际上是一个封装了业务逻辑的Java类.
Why EJB?
1. 最重要的理由:分布式!分布式对象之间互相协作,完成特定的业务功能。分布式对象之间应该实现分布式透明(或位置透明)。即在客户端代码中无需指定分布式对象位置(通过配置来解决);
2. 分布式对象之间的事务支持(RMI不支持事务);
3. 应用程序需要支持不同的客户端,只需要少量的代码, 就可以让远程客户端访问到企业级Bean。
如果你的应用需要进行分布式部署、如果你的分布式对象需要支持事务、如果你的关键业务逻辑需要能够支持多种不同类型的客户端,那么EJB将是一个很好的选择。
这样就可以支持webservice,支持webservice就意味着支持“异构系统”之间的沟通, 例如客户端可以使Java, C++, C#, Delphi等。Corba是一种具体的实现, EJB相对于Corba较简易一些。
EJB的基本分类:
Enterprise Bean - 企业Bean:
1> Session Bean - 会话Bean:
1. Stateless Session Bean - 无状态会话Bean;
2. Stateful Session Bean - 有状态会话Bean;
2> Message Driven Bean (MDB) - 消息驱动Bean, 基于JMS;
Persistece - 持久化:
Entity Bean - 实体Bean.
说明: 在EJB2中, Entity Bean分为BMP(Bean管理持久化实体Bean) 和 CMP(容器管理持久化实体Bean)(由容器对实体Bean进行CRUD)。【二-17:00】对于EJB3中, 所有的Entity Bean全部都是CMP。
Session Bean(会话Bean):
1. 会话Bean可以执行业务逻辑操作,比如注册用户、订单登记、数据库操作等等;
2. 什么叫会话(Session):
1> 即从客户端获得EJB对象开始,然后调用EJB的方法(可以是多次),直到客户端生命周期结束, 或客户端释放了EJB对象为止,成为一次会话;
2> 随着会话的终止, EJB对象也有可能被EJB容器销毁。

在客户端获得容器中EJB对象的过程中需要使用JNDI, 通过指定EJB在容器中的名称进行查找, 示例代码如下:
InitialContext context = new InitialContext(); FirstEjb ejb = (FirstEjb)context.lookup("FirstEjbBean/remote"); String s = ejb.saySomething("张三"); System.out.println(s);
EJB与Spring的默认机制不同, 每次通过JNDI查询一个Bean的时候, 容器会新创建个一个对象; 而Spring中的Bean是每次查询的时候会使用已有的具名Bean.
状态的概念:
什么是对象状态?
对象的状态是有其实例变量(即成员变量)的值组成的
1. 实例(非静态)变量: 即不同的实例, 其内部成员变量的值是不一样的.
2. 类(静态)变量: 相同的类, 但是不同的实例之间维护这同一份内部成员变量的拷贝.

什么是有状态的会话Bean:
即EJB能够为同一个客户端在多次请求(方法调用)之间保持状态信息;
比如:基于某种原因(可能是因为系统要求支持多种不同类型的客户端), 购物篮功能作为系统的核心业务, 需要由EJB对象来担当(而不是由HTTP SESSION对象)。那么EJB必须能够区分不同的客户端, 并且分别为不同的客户端保持与其对应的状态信息。
即,从某个客户端的角度来看, 似乎EJB对象正在被该客户端独占了一样, 不会因为有任何其他的客户端同时对同一个EJB访问而影响其最终的计算结果。
从HTTP Session原理入手了解Stateful Session Bean 的原理:
比如在购物过程中, HTTP Session的交互过程:

有状态(Stateful EJB)的EJB是通过为每一个会话创建一个EJB实例对象来为每一个客户端服务, 某一个实例与客户端交互的过程就是一个会话交互的过程。【二-35:00】

上图中的Token令牌就相当于HTTP交互过程中的JSESSIONID一样, 用于标识每一个会话.
每一个客户端当连接到服务器之后(通过Lookup方法查找),服务器均会给其一个令牌, 那么以后的每次请求都会带着这个令牌到服务器端, 这样服务器就能区分每一个客户端了。
当客户端释放了某一个连接之后, 服务器就会把被释放的EJB实例回归到EJB实例池中。
什么叫无状态的会话Bean(Stateless Session Bean)
1. 并非说是EJB不能存在状态, 而是说EJB容器不会对EJB的状态做管理;
2. EJB容器会使用实例池的方式,甚至单例的方式来实现无状态的Session Bean;
3. 因为EJB容器不会对Stateless Session Bean的状态进行管理, 所以它的性能要比Stateful Session Bean 好。
注: 在JBoss服务器中, 实现上面无状态Session Bean 就是通过单例的方式来实现(在服务器中使用单力方式来管理Bean)。
总结:
1. 有状态EJB:客户端每次初始化连接的时候, 服务器为客户端新创建一个对象;
2. 无状态EJB:客户端每次连接的时候, 不管有多少个客户端连接, 服务器返回的EJB对象是一样的;
浙公网安备 33010602011771号