Java学习笔记-《Java程序员面试宝典》-第5章Java Web-5.2J2EE与EJB(5.2.5-5.2.10)

来源:互联网 发布:cf鬼跳宏数据 编辑:程序博客网 时间:2024/06/10 20:59

5.2.5 EJB有哪些生命周期

Stateless Session Bean的声明周期是由容器决定的,当客户端发出请求要建立一个Bean的实例时,EJB容器并不一定要创建一个新的Bean实例来供客户端调用,如果当前有Stateless Session Bean的实例能够满足客户的需求,就不会去创建新的实例。对于Stateless Session Bean来说,实例的创建和删除都是由EJB容器来控制的。Stateless Session Bean的生命周期共有两个状态:No Staet(无状态)和Method Ready(准备方法),下图是两种状态的转移图:
这里写图片描述
其中,No State表示容器中没有Stateless Session Bean的实例。只有EJB容器认为实例池中需要更多的实例为客户提供服务时,才会去创建新的实例,此时新创建的实例就由No State转换为Method Ready状态;相反,如果EJB容器认为当前实例池中已经不需要这么多的实例来给客户端提供服务,就会根剧某些策略从实例池中删除一些实例,这些被删除的实例的状态就转换为No State。
Stateful Session Bean的生命周期是与用户的操作相关联的,由于Stateful Session Bean不能被共享,因此当客户端第一次调用一个Stateful Session Bean时,容器必须立即在服务器中创建一个新的Bean实例,并关联到客户端上,以后当此客户端调用Stateful Session Bean的方法时,容器会把调用分派到与此客户机相关联的Bean实例。Stateful Session Bean的实例在生命周期中共有三个状态:No State、Method Ready和Passivated(钝化)。转态转换如下图:
这里写图片描述
其中,No State表示容器中没有Stateful Session Bean的实例。只要有新的用户请求到来,EJB容器就会创建新的Stateful Session Bean实例,此时被创建的实例的状态就从No State转换为Method Ready。当这个实例不再被使用时(客户端不再使用或客户端超时),EJB容器就会删除该实例,此时这个实例的状态就会转换为No State。与Stateles Session Bean不同的是,Stateful Session Bean不能被共享,因此在某一刻EJB容器中可能会有大量的Stateful Session Bean实例,从而导致内存开销过大,为了解决这个问题,在Stateful Session Bean的生命周期中引入了另外一个状态—Passivated。当Stateful Session Bean实例过多时,EJB容器只保留那些正在被使用的实例,从而把当前不被使用的实例从内存移到持久存储介质上(例如硬盘),此时这些实例的状态就转换为Passivated。只有当客户再次请求使用处于Passivated状态的实例时,这些实例才会被激活并恢复到内存中,同时其状态变为Method Ready。当实例不再被使用或超时后,其状态都会转换为No State。
Method Ready状态与Passivated状态之间通过根据MRU或NRU算法进行迁移。转态迁移前会调用对应的ejbActive()和ejbPassive()方法。
Entity Bean能存活相对较长的时间,并且状态是持续的。只要数据库中的数据存在,Entity Bean就一直存活,而不是按照应用程序或者服务进程来说的,即使EJB容器奔溃了,Entity Bean也是存活的。Entity Bean的生命周期能够被容器或者Bean自己管理。为了很好地管理Entity Bean,它的生命周期划分为3个状态,转换如下:
这里写图片描述
其中,No State同样表明实例不存在。当EJB容器创建新的实例之后,被创建的实例会进入Pooled State,处于这个状态的实例不会与任何EJB对象关联,与数据库记录对应的字段也未初始化;当客户端调用Home接口中的方法来创建或找到某个实体Bean时,该实体的状态就会从Pooled State转换到Ready State,处于Ready State的实例已经建立了与EJB对象的关联,同时也已经和数据库中的记录对应起来了。与Session Bean一样,当Entity Bean的对象不再使用时其状态就会转换为No State。

5.2.6 EJB的角色有哪几种

EJB将开发部署EJB应用的任务划分到了6个不同的角色,它们分别为Enterprise Bean Provider(企业级组件开发者)、Application Assembler(应用组合者)、EJB Deployer(EJB 部署者)、EJB Server Provider(EJB 服务器提供者)、EJB Container Provider(EJB容器提供者)和System Administrator(系统管理员)。每个角色都可以由不同的开发商提供,每个角色所做的工作都必须严格遵循EJB规范,并保证彼此的兼容性。
下图为EJB中的6个角色及其功能概述:
这里写图片描述
需要注意的是,以上6个角色可以由不同的开发商提供,但有一个前提,即他们都必须遵循EJB规范并且保证相互之间的兼容性。

5.2.7 EJB的开发流程是怎样的

在JEB的开发流程中有非常重要的3个对象:Remote接口、Home接口和Bean类。其中Remote接口定义了业务方法,用于EJB客户端调用业务方法,需要注意的是,开发EJB时,只需要对其进行定义即可,并不需要去实现它,因为容器会在编译时会根据接口定义和Enterprise Bean类的内容自动去创建一个实现了该接口的类。Home接口提供了产生和定位Remote接口实例的方法,用于EJB工厂创建、移除、查找EJB实例,它又分为远程Home接口与本地Home接口两种。Bean类指的是实现了javax.ejb.EnterpriseBean接口的类,它定义了应用的商业逻辑。
具体而言,EJB开发步骤如下所示。
1>定义Remote接口。编写一个接口继承自javax.ejb.EJBObject。在这个接口中定义需要实现业务逻辑的方法对应的接口。需要注意的是,这个接口中定义的类都必须抛出RemoteException异常,实例如下:

import javax.ejb.*;import java.rmi.*;public interface HelloInterface extends EJBObject{    String hello() throws RemoteException;}

2)编写一个接口继承javax.ejb.EJBHome。这个接口中实现create()方法,这个方法的返回值必须为Remote接口类型(可以被远程访问的接口),同时这个方法还需要抛出两个异常:CreateException和RemoteException。create()方法取代传统OO(Object Oriented,面向对象)中的constructor(构造方法)来初始化一个对象。EJB容器可以维护一定数量的对象实例,示例如下:

import javax.ejb.*;public interface HelloHome extends EJBHome{    public HelloInterface create() throws    java.rmi.RemoteException.javax.ejb.CreateException;}

以上这个例子中的create()方法返回值为上面创建的HelloInterface接口。
3>编写ben类的实现类(SessionBean)。实现类必须实现下面5个方法:
public void ejbCreate()方法、
public void ejbRemove(){}方法、
public void ejbActivate(){}方法、
public void ejbPassivate(){}方法、
public void ejbSessionContext(SessionContext ctx){
this.ctx = ctx;
}方法
以上的四个方法(ejbRemove()、ejbActivate()、ejbPassivate()、ejbSessionContext())主要用来控制SessionBean的生命周期。具体而言,容器在删除enterprise bean的实例之前会调用其ejbRemove()方法。容器在将enterprise bean的实例从临时持久存储介质加载到内存中后会调用其ejbActivate()方法。容器将enterprise bean的实例转移到临时持久存储介质之前会调用其ejbPassivate()方法。每次创建一个SessionBean时,容器会调用setSessionContext()方法,用来初始化enterprise bean使用的SessionContext变量。具体代码如下:

import javax.ejb.*;public class HelloBean implements SessionBean{    SessionContext context;    public void ejbActivate(){}    public void ejbPassivate(){}    public void ejbRemove(){}    public void ejbSessionContext(SessionContext ctx){        this.ctx = ctx;    }    public String hello(){        return "Hello World!"    }}

4>在项目的META-INF目录中创建两个文件:ejb-jar.xml和jboss.xml。其中,ejb-jar.xml文件的内容如下所示:

<ejb-jar>    <enterprise-beans>     <session>         <ejb-name>HelloBean </ejb-name>         <home>HelloHome </home>         <remote>HelloInterface </remote>         <ejb-class>HelloBean </ejb-class>         <session-type>Stateless</session-type>         <transaction-type>Container </transaction-type>     </session>    </enterprise-beans></ejb-jar>

jboss.xml文件的内容如下所示:

<jboss>    <enterprise-bean>     <session>         <ejb-name>HelloBean</ejb-name>         <jndi-name>Hello</jndi-name>     </session>    </enterprise-bean></jboss>

5>把上述EJB项目发布到JBoss容器上以后,客户端就可以调用该EJB对象了。
客户端调用EJB步骤如下:设置JNDI服务工厂以及JNDI服务地址系统属性,查找Home接口,从Home接口调用create()方法创建Remote()接口,通过Remote接口调用其业务方法,示例如下:

import javax.naming.*;public class Client{    public static void main(String[] args){        try{            Context initial = new InitialContext();            //从JNDI中以Hello名字来定位到对象            HelloHome home = (HelloHome)initial.lookup("Hello");            HelloInterface h = home.create();            System.out,println(h.hello());        }catch(Exception e){            System.out.println(e.getMessage());        }    }}

5.2.8 EJB3.0与EJB2.0有那些不同之处

EJB3.0在EJB2.0的基础上,引入了更多的概念,并且它对开发过程实现了进一步的简化,使得开发过程变得更加方便。具体而言,就是在系统开发时,不再像EJB2.0那样需要两个接口和一个Bean的实现类,它主要通过annotation元注释来Session Bean的类型,例如,再实现上例中的Stateless Bean时就可以用下面的方式来实现:

import javax.ejb.*;@Stateless@Remotepublic class HelloBean{    public String hello(){        return "Hello World";    }}

从这个例子可以看出,EJB3.0在开发时省去了许多方法(例如ejbCreate()、ejbRemove()等),大大简化了开发工作。
EJB3.0与EJB2.0最大的不同之处就在于EJB3.0听过元数据、去掉部署文件、省去对Home接口的使用等方法简化了开发的工作。此外,在访问数据库的方法上也有所不同:EJB2.0在访问数据库时使用的是Entity Bean,而EJB3.0用的是JPA(Java Persistance API)。

5.2.9 EJB容器有哪些作用

所有EJB都必须运行在EJB容器中,EJB容器是在Entity JavaBean的拥有者,它负责管理运行在其中多个bean。EJB容器提供了许多服务,使得开发人员只需要把开发重点放在业务逻辑上。具体来说,EJB容器提供了一些非常重要的服务:事务管理、持久性管理、安全管理、并发访问控制管理、生命周期管理和代码生成等。

5.2.10 EJB规定EJB中禁止的操作有哪些

具体而言,EJB规范规定EJB禁止的操作有以下八种:
1>不能操作线程和线程API
2>不能操作AWT(Abstract Windowing Toolit,抽象窗口工具包)
3>不能实现服务器功能
4>不能对静态属性存取
5>不能使用IO操作直接存取文件系统
6>不能加载本地库
7>不能将this作为变量,不能将this返回
8>不能循环调用

阅读全文
0 0
原创粉丝点击