EJB学习笔记

2004-10-13     星期三      晴

服务器端计算(使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第一天))

1.  单层(桌面系统)
答: 1) GUI客户端、应用程序以及资源全都在同一台机器(同一层);

2.  二层(服务器/客户端)
答: 1) 胖客户端;
    2) 应用和资源在同一层;
    3) 服务器端程序更新将导致所有客户端程序更新

3.  多层架构体系历史
答: 1) 多层架构体系经历了几个主要的改进:这种改进从单层(主机类型系统)到二层(服务器/客户端);
    2) 在早期九十年代期间,传统企业信息系统提供商开始将二层模型改进为更柔性的三层以及多层应用模型以满足客户需求;
    3) 多层模型将软件部署于一组机器,这些组成了整个应用程序。这个新式的模型将商业逻辑从系统服务以及用户界面分离出来,置于介于二者之间的中间层;
    4) 新的中间件服务的发展(事务监听器、消息导向器)给了这种新的架构体系额外的推动力;
    5) 此外,企业应用程序在互联网以及内部网中的增长使用,突显了以Web浏览器作为客户端的轻便、容易部署。
    6) 多层设置简化了企业应用程序的开发、部署以及维护。它使开发者能专注于商业化逻辑,依赖于不同的后端服务提供客户端应用以满足用户交互。
    7) 一旦完成开发,商业化逻辑能被部署于服务器满足一个组织既存的需求;
    8) 无论如何,没有标准组件结构体系存在于中间层,这迫使开发员专注于不同平台、开发系统以及中间件服务的细节。这限制了开发者部署单层应用程序于不同平台以及满足不同商业条件的挑战。

4.   EJB是多层架构体系的解决方案
答: 1) EJB(Enterprise JavaBeans)是一种服务器端组件架构,这种组件基于用Java写的分布式的应用程序;
    2) 拥有Java和多层架构体系的双重好处;
    3) 是一个标准的中间件;
    4) 自从几年前提出来,EJB技术已获得平台供应商和企业开发团队的充分支持。这是因为EJB组件简化了轻便、可扩展商业化组件的开发。
    5) 通过提供系统级别服务的自动支持,EJB服务器降低了开发商业化组件的复杂性这些服务包括事务处理、安全以及数据库连接。这使得开发者开发者能集中精力开发商业化逻辑。
    6) EJB架构体系是一种开发和部署以组件为基础的商业化程序的组件架构。

5.  EJB规范的目标
答: 1) EJB规范的目标是定义一个标准,不同的供应商能实现这些标准;
    2) 因为这个标准定义了框架有关的每一个本质上的细节,应用EJB框架写的程序均是可扩展、事务处理以及多用户安全的。此类的应用程序只要写一次,然后可部署于任何支持EJB的服务器平台上。

6.  EJB环境总览
答:1) EJB组件运行于EJB服务器的容器中;
    2) 容器可连接数据库或其它组件;
    3) EJB客户端可访问同一虚拟机中或通过远端接口访问不同虚拟机中企业Bean;
    4) EJB home组件可以看成是EJB对象的工厂;
    5) 从home组件中得到EJB对象可以是在本地也可以是远端接口。

7.  EJB的好处
答:1) 众多网站打算以及正在使用Java,但没有得利用EJB技术。开发者已使用Servlet/JSP模式,在没有应用服务器的帮助下通过JDBC内置的提交和回滚技术进行事务处理。
    2) 这样做的时候,程序开发员面临许多挑战:一些最重要的包括并发处理,持久化以及事务处理。作为结果,开发员要么自行开发要么购买支持的框架。
    3) 通过使用企业Bean,这些问题都得到了解决。企业Bean的使用允许开发者专注于商业逻辑,将他们从基础结构以及中间件逻辑中解放出来。开发者因而变得更富生产力和效率。

8.  何时使用EJB
答:1) 分布式对象
       当使用企业级的JavaBean, 分布式对象用于建立企业级别的系统。这意味着你的系统可以部署于不同的物理机器,由此可产生许多彼此独立的进程,以达到性能、可扩展性、可用性的系统目标。
    2) 可移殖地组件框架
       对于许多具有远见的用户,他们所关注的问题是是否可达到平台无关、供应商和应用服务无关。EJB架构,这个工业化标准架构,能帮助达到这些目标。例如:在WebSphere上开发的企业bean可用于非IBM的应用服务器。
    3) 对象持久化
       a. 对象持久化意味着他的状态(它变量的值)能被保存。大多数情况下,一个持久化对象保存在关系型数据库中。
       b. 不幸的是,对象和关系型数据库相互差异太大。和JAVA相比,关系型数据库拥有有限的模型化能力,诸如对象继承和封装。此外,最主要的转换问题是SQL数据类型和Java的数据类型并不完全匹配。所有的这些问题在使用CMP实体Bean时都得到了解决。
    4) 数据库架构无关
       EJB技术使商业逻辑从数据库访问中清楚地分隔开来。商业逻辑和数据库架构无关并能部署入不同或者变化的数据库架构中。
    5) 事务管理
       a. 对共享数据的并发访问是令开发者最头痛的问题之一。所有相关需要考虑的问题诸如数据库锁定,数据完整性丢失事件可以导致创建高度复杂的框架以管理数据库级别的共享数据的访问。
       b. EJB自动处理这些复杂的线程和并发的共享数据问题。正如前面提到的,EJB容器提供了所有必须的事务服务给企业Bean去管理后台的数据。
    6) 中间层架构
       a. 许多公司认为他们的应用软件,特别是商业规则和数据库架构,是一个有效的资产。因此他们关注在互联网情况下如何保护它们。
       b. EJB使得一个公司可使用中间层架构,因此表现层和逻辑层分隔开来。这种分隔使得第二个防火墙的使用成为可能。
    7) 多个服务器的产能和可用能力
       a. 在过去的几年,客户发现胖客户端简单,但扩展性差而基于Web的系统这方面却强。与此同时,软件分布式问题也使得胖客户端大为减少。
       b. 一周七天,一天二十四小时的正常运行时间是商业至关紧要的问题。开发者应能设计出合格的系统使这成为可能。
       c. 客户所需要的是一种写商业逻辑的方式以满足各种需求。WebSphere的EJB支持可提供这种高度的可扩展性。它利用以下特征实现:
          对象捕获和分享:WebSphere应用服务器自动在服务器层集中企业Bean,降低了花费于对象创建和垃圾收集的时间。在大多数据进程中这样使运行成为可能。
    8) 容错的克隆支持
       a. 有多个clones能够处理请求,这样故障不会破坏运行和可靠性。多个克隆分布于不同的节点,整个机器失败而不会产生灾难性的结果。  
       b. WebSphere应用服务网络部署支持分布、克隆和自动容错。

9.  J2EE和J2SE
答:1) J2EE代表Java 2的企业版本
    2) J2EE是用以服务器端开发的一组强健的中间件应用服务;
    3) J2EE是Java 2标准版的扩展
    4) J2EE使所有Java的企业级API和功能性成为可能,并以一个整体访问。这简化了开发、部署以及多层管理中的复杂问题。

10. J2EE平台技术
答:1) 组件(Servlet、JSP、EJB):
       a. 系统应用一层的单元;
       b. 由应用开发者实现;
       c. 运行于Container内;
       d. 提供相应的服务和通讯
    2) 服务
       a. 为J2EE提供相关功能;
       b. 由J2EE平台提供商实现API;
    3) 会话
       a. 由container提供,用以协作组件;

11. MVC架构模式
答:1) Model: 模型层,由EJB实现;
    2) Controller: 控制层,由Servlet实现;
    3) View: 界面层,由JSP实现。

12. Facade
答:1) 由封装的对象完成商业逻辑,暴露的对象完成任务接受以及完成的应答

13. J2EE技术
答:1) Servlet:
       a. 一种J2EE组件;
       b. servlet可被认为是运行在服务器端的applet;
       c. Servlets提供了基于组件、平台无关的方法用以构建基本Web的应用程序。
    2) JSP
       a. 一种J2EE组件;
       b. 代表Java服务器端页面;
       c. JSP技术是servlet的扩展,可以认为是HTML + JSP tags。
    3) EJB
       a. 一种J2EE组件;
       b. 代表企业级的Java Bean;
       c. EJB定义了服务器端组件是如何被编写以及提供了在组件和管理它们的服务器和组件间的标准架构协议;
    4) JDBC
       a. 一种J2EE服务;
       b. JDBC代表Java Database Connectivity;
       c. JDBC对大范围关系型数据库提供了统一的访问, JDBC2.0提供了数据库连接池的支持。
    5) RMI和RMI-IIOP
       a. 一种J2EE服务;
       b. RMI代表远端方法调用(remote method invocation);
       c. IIOP-Internet Inter-ORB协议;
       d. RMI是一种调用远端方法的一种机制。EJB依靠RMI作为同一机器或不同机器组件间的一种会话API;
    6) JNDI
       a. 一种J2EE服务;
       b. 代表Java命名和目录接口(Java Naming and Directory Interface);
       c. 在以EJB为基础的应用程序中,当客户端需要访问EJB组件,JNDI用于确定和得到组件以服务于客户端。
    7) JMS
       a. 一种J2EE服务;
       b. 代表Java消息服务(Java Messaging Service);
       c. 通过结合Java技术于企业消息,JMS API提供了一个新的,强有力的工具以解决企业计算问题。通过定义一组消息概念和编程策略,JMS API提升了程序员的生产效率;
       d. 异步通讯;
    8) JTA和JTS
       a. JTA代表Java Transaction API;
       b. JTS代表Java Transaction Service;
       c. JTA是高级别的传输API,允许应用程序和J2EE服务器管理事务;JTS表明了事务管理器的具体实现。
    9) security
       a. J2EE访问控制包括鉴定(authentication)和授权(authorization);
       b. 鉴定(authentication):确定用户身份(基于角色);
       c. 授权(authorization):确定用户是否有权访问请求资源;
    10) Containers
       a. 每个组件运行于J2EE平台提供商提供的容器内;
       b. 容器提供了特定的部署和运行服务(生命周期、安全,事务等);
       c. 能提供什么服务依赖于组件的类型。
    11) Web和EJB容器
       a. 通过调用JSP和servlet以及返回结果给客户端,Web组件提供给客户端以运行时支持;
       b. 简单的EJB容器提供事务、EJB组件状态管理以及lookup、安全等的自动支持;

2004-10-14     星期四      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第二天)

1.  EJB
答:1) EJB提供给服务器端以组件为基础的分布式计算的框架;
    2) EJB典型地代表一种商业处理过程,可以跨应用、跨网络。

2.  EJP角色
答:EJB规范对于EJB开发和部署定义了六种角色。每种角色在EJB开发过程中承担不同的责任:
    1) Bean provider:
       代码开发者,他负责将商业需求转化为物理代码。他提供必须的EJB、Class以及部署描述文件。
    2) Application assembler
       有点像Bean provider,或者高级的团队领导。它的职责是打包所有的EJB组件以及其它应用程序组件,最后的产品是EAR文件。
    3) Deployer
       将EAR文件部署到应用服务器
    4) Server provider
       提供EJB的服务器环境
    5) Container provider
       提供EJB的容器环境,通常和server provider一样。
    6) System administrator
       确保运行环境正确配置,程序功能正确。

3.  主要的EJB框架组件
答:这里有六种主要的EJB框架组件技术:
    1) EJB server:
       提供给所有EJB主要的服务。包括一至多个EJB容器。通常也被称为EJS。
    2) EJB container:
       提供了EJB实例的运行环境,是服务器和EJB组件的中间层。
    3) EJB component:
       这些代表真正的EJB本身。有三种类型的企业beans:(实体Bean)entity、(会话Bean)session和(消息驱动Bean)message-driven bean。
    4) EJB interface and EJB bean:
       客户端访问的接口和EJB bean类;
    5) EJB deployment descriptor:
       定义了运行环境下,EJB的Container应该给EJB提供什么服务。Bean之外的一个文件。
    6) EJB client:
       访问EJB的客户端, 包括Servlet,其它EJB或者Java Application。

4.  EJB服务器
答:1) EJB服务器是应用程序服务器中有EJB容量的部分;
    2) 有时叫做EJS;
    3) 容器对于客户端是不可见的----没提供客户端操作容器的API,无法告之客户端企业bean被部署于哪个容器;
    4) EJB服务器提供给所有企业Java Bean公共服务的实现。EJB服务器有责任把复杂的东西隐藏。EJB规范略述了EJB服务器必须实现的七种服务:
       a. Naming(JNDI)
       b. Transaction(JTA and JTS)
       c. Security()
       d. Persistence(JDBC)
       e. Concurrency()
       f. Life cycle()
       g. Messaging(JMS)
    5) EJB容器和EJB服务器并没有清楚的分隔,EJB没有直接和EJB服务器打交道,而是通过EJB容器——它更像一个经济人,将EJB服务器的服务提供给EJB。因此,在EJB看来,EJB容器提供了这些服务。此外,规范只定义了bean和容器的合约。而没有定义容器-服务器合约。

5.  EJB容器
答:1) EJB容器是一个系统,它的功能类似于提供一个运行环境管理企业bean以及提供运行期间管理所需的主要服务。此外,作为EJB服务器提供的七种服务的中介,EJB容器也提供EJB实例的生命周期管理和EJB实例鉴定。
    2) EJB容器创建bean实例,管理实例池以及销毁它们。容器提供了部署描述符中指明的服务。例如,它将开始事务处理或较验安全。

6.  远程访问能力
答:1) 通常,EJB是远程、分布式对象,容器的主要责任之一是提供一种中介以访问这些远端对象。
    2) 远程访问使对网络组件的远程调用转为一个本地组件的调用。
    3) EJB容器使用Java RMI接口提供给EJB容器远程访问能力。

7.  主要的服务——命名
答:1) 客户端可通过在一个集中的命名空间——命名服务器——寻找bean的名字调用企业bean, 这种访问通过JNDI。当服务器启动时,容器有责任注册唯一的可寻找的名字于JNDI名址,并绑定适当的对象类型。

8.  主要的服务——事务
答:1) 一个事务被定义为必须在一起执行的一组任务:要么一起做要么一起不做。
    2) 当bean的事务被激活,EJB容器执行事务操作。EJB事务行为被描述于部署描述符中,这也被称为CMT(container-managed transactions)。因为容器管理着事务,容器可被重写而无须清楚的划分事务。

9.  主要的服务——安全
答:1) 对于企业bean, EJB容器提供了一个安全域。容器有责任使安全政策通过存取访问控制列表(ACL)在部署的时候被定义。
    2) 存取访问控制列表是一个有关用户、用户所属组以及也们的权限的一个列表。它确保用户只访问他们给定权限范围内的资源。

10. 主要的服务——持久化
答:1) 容器同样有责任管理bean的持久状态,它通过同步bean在内存中的状态于数据库中实现。

11. 主要的服务——并发访问
答:1) 并发访问是指同一个bean被二个及以上数量的客户端访问,容器根据bean类型进行并发管理。

12. 主要的服务——生命周期
答:1) 容器有责任控制部署组件的生命周期。当EJB客户端给容器发出请求,容器动态地初始化,销毁以及重用相应的bean。

13. 主要的服务——异步通讯
答:1) 容器必须提供异步通讯,特别是在客户端和消息驱动bean之间。

14. EJB组件
答:1) EJB组件指bean本身,这包括所有的类、接口以及其它。
    2) 有三种类型的企业bean:
       a. 实体bean
          . 代表商业实体或项目相关概念;
          . 一个企业bean对应一个table;
          . 一个实例对应table中一行;
          . bean中实例变量对应于table中字段。
       b. 会话bean
          对应于商业任务,完成一系列活动;
       c. 消息驱动bean
          完成一定的商业活动,通过异步通讯去监听动作。

15. 同步调用和异步调用
答:1) 同步调用:等待被调用的对象执行完成后才执行下一个调用;
    2) 异步调用: 对其它对象的调用无须等待,调用集中处理;

16. EJB接口和EJB bean
答:一个EJB组件由以下主要的元素组成:
    1) EJB组件(本地或远端)接口: 通过组件接口可以访问组件方法;
    2) EJB home接口:管理bean的生命周期;
    3) EJB bean 类:包括了所有真实的商业逻辑,提供了所有商业逻辑实现;
    4) 主键类

17. EJB组件接口
答:1) 客户端通过组件接口获得bean的访问能力。它定义了客户端可见的商业方法;
    2) 在bean class中必须有组件接口中对应的商业方法;
    3) 消息驱动bean没有组件接口,因为它不会被客户端调用;
    4) 客户端访问组件接口,容器获得请求,然后将请求转至具体bean;
    5) 有两种类型的组件接口:本地和远端。一个特定的用户自定组件接口也许只实现其中一种类型。

                                java.rmi.Remote
                                       ↑
                                       |
    javax.ejb.EJBLocalObject  javax.ejb.EJBObject(组件接口)
               ↑                      ↑
               |                       |
          MyBeanLocal               MyBean

2004-10-15     星期五      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第三天)

1.  本地与远端接口
答:1) EJB中通常存在的是远端接口,这使得容器或虚拟机之外的EJB客户端能访问分布式对象;
    2) 在远端调用中,方法参数和返回对象都是通过值进行传递。两端对象序列化以及网络反复传递产生非常大的资源消耗,这降低了性能。但这样达到了位置无关。
    3) 本地接口(since EJB 2.0),为同一个虚拟机中的客户端访问EJB成为可能。
    4) 在本地调用中,方法参数通过引用传递,执行是在同一个虚拟机中,因此不存在序列化以及网络反复传递,更为高效。
    5) 假设实体bean仅被会话bean调用而没有直接被外部客户端调用,对于实体bean只提供本地接口更为有意义。

2.  商业方法定义
答:1) 作为一个bean的提供者,我们必须在我们组件接口中定义我们bean的商业方法。因为它是一个接口,我们仅需定义这个方法。
    2) bean class必须提供接口中定义方法的真实实现。

3.  EJB home接口
答:1) EJB home接口提供服务创建和查找bean的实例,这给EJB客户端提供了EJB的能力。
    2) Home接口定义了bean的生命周期方法,他提供了对bean生命周期的基本管理能力。
    3) 消息驱动bean没有home接口,因为他不直接被客户端调用。
    4) 客户端永远不会真正访问一个bean的实例,它访问的是EJBObject。
    5) EjbHome对象实现了home接口。起初,EJB容器初始化企业bean对应的EJBHome对象并在命名服务器中注册这个home。
    6) EJB客户端通过JNDI访问EJBHome对象。
    7) 有两种类型的组件接口:本地和远端。

                                java.rmi.Remote
                                       ↑
                                       |
    javax.ejb.EJBLocalHome     javax.ejb.EJBHome(主接口)
               ↑                      ↑
               |                       |
        MyBeanLocalHome            MyBeanHome

4.  Home接口的方法:生命周期方法
答:1) 作为一个bean的提供者,我们必须在home接口中定义企业bean所须的生命周期方法。
    2) Create方法:在home中,返回的值是bean的组件接口。Bean可能有零到多个创建方法,这依赖于bean的类型:
       a. 没有状态的session bean必须只有一个没有参数的创建方法;
       b. 有状态的session bean至少有一个创建(有或没有参数)方法;
       c. 实体bean可能拥有零或多个创建方法。
       在创建方法时发生的行为也依赖于bean的类型, 对于实体bean, 每Create一次可理解在table中插入一行。对于session bean, Create意味着创建bean实例。
       Finder方法:只对实体bean有效, 他们是在数据库中寻找实体bean代表的持久数据。每一个实体bean的home接口必须有一个以实例主键作为参数的方法:FindByPrimaryKey()。一个finder方法返回的值是bean组件接口或一个(组件接口)集合。

5.  EJB bean class
答:1) bean class包括所有真实的企业bean的商业逻辑;
    2) bean class没有直接的客户端视图,和客户端直接打交道的是组件或home接口。因此本地或远端视图这种思路不能应用于构建这种类。
    3) 有三种不同类型的bean class: 实体bean、会话bean以及消息驱动bean。
    4) 我们必须选择一种实体Bean接口去继承,要么是实体bean、要么是会话bean以及消息驱动bean。
    5) 此外,假如我们正构建一个消息驱动bean, 我们必须也实现MessageListener接口(具体的商业逻辑编写处)。

                                       javax.ejb.EnterpriseBean
                                                 ↑
                         |ˉˉˉˉˉˉˉˉˉˉˉˉ|ˉˉˉˉˉˉˉˉˉˉˉˉ|                   
                javax.ejb.EntityBean  javax.ejb.SessionBean   javax.ejb.MessageDriverBean
                        ↑                       ↑                       ↑
                   MyEntityBean             MySessionBean          MyMessageDriverBean
                                                                          ↓
                                                                javax.jms.MessageListener

6.  实现bean class接口的回调方法
答:1) 在bean class中必须实现的方法依赖于我们选择的接口类型。这些方法不是提供给客户端控制,而是给容器以管理这些Bean。
    2) 这些方法称为容器的回调方法,是之前我们讨论的bean和容器中合约的一部分。
    3) 对于这些方法,容器没有任何的常规行为。我们必须在自己的bean class中具体实现他们。
       javax.ejb.EntityBean
       . void ejbActivate()
       . void ejbLoad()
       . void ejbPassivate()
       . void ejbRemove()
       . void ejbStore()
       . void setEntityContext(EntityContext ctx)
       . void unsetEntityContext() 
       javax.ejb.SessionBean
       . void ejbActivate()
       . void ejbPassivate()
       . void ejbRemove()
       . void setSessionContext(SessionContext ctx)
       javax.ejb.MessageDriverBean
       . void ejbRemove()
       . void setMessageDrivenContext(MessageDrivenContext ctx)
       javax.jms.MessageListener
       . void onMessage(Message message)
 
2004-10-18     星期一      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第四天)

1.  构建bean class
答:1) 构建bean class意味着商业逻辑的实现;
    2) 作为bean的提供者,在bean class中我们必须实现所有必要的方法。有以下四种类型的方法:
       a. 实现组件接口中申明的商业方法:
          必须确信在bean class中有与组件接口中对应的方法(名称、参数个数、数量、顺序一样,抛出异常、返回类型可不同);
       b. 实现主接口(Home interface)中的生命周期方法:
          bean class必须实现定义于主接口中的生命周期方法。与组件接口中实现不同的是,方法可不完全一致:
          i.  Create方法:与定义于主接口中每个create方法对应,ejbCreate方法和ejbPostCreate方法必须存在于bean class中。在bean class创建之前,ejbCreate方法被容器调用以为bean的创建作些准备。ejbPostCreate方法在bean class创建后由容器调用。主接口中Create方法返回一个组件接口(Componet interface),bean class中ejbCreate方法返回主键(或主键的集合)。
          ii. findByPrimaryKey: 只对实体bean有效。主接口中find方法返回一个组件接口(Componet interface),bean class中find方法返回主键。
          iv. find方法:主接口中findXXX 方法对应于bean class中ejbFindXXX 方法。
          v . Home方法:主接口中Xxx 方法对应于bean class中eejbHomeXxx 方法。
       c. 实现容器的回调方法:
          bean class必须提供在其超类中定义的容器回调方法。
       d. 其他方法:
          例如message-driven bean的MessageListener接口中的onMessage()方法,以及一些自定义的方法。

2.  EJB部署描述符
答:1) 运行时bean如何被管理的有关信息并不位于先前我们讨论的接口和类中,而是位于部署描述符中。
    2) 部署描述符文件是一个XML文档,它描述了组成一个应用程序的bean的一些结构化的信息。这些信息包括bean的类型、组成接口以及扩展信息、运行时如何动作等。它描述了诸如安全、事务、命名以及容器的其他服务。
    3) 部署描述符文件是必须打包入EJB的JAR文件中的组件之一。

3.  EJB客户端
答:1) 按照先前提到的,从EJB客户端看来,所有的交互作用对象都实现了home和component接口。EJBHome接口是实现了home接口的真正对象,用于管理bean的生命周期方法(create,find,remove)。EJBObject是实现了component接口的真正对象,被客户端用于访问bean的商业方法。在部署时,这二者由容器产生。
    2) 应该记住的是我们永远不直接和EJB bean实例打交道,因为每件事都通过EJBObject和EJBHome被管理。
    3) 在分布式对象代理间存在会话,但于EJB而言,它不管这种调用是通过远端还是本地接口实现。

4.  远端与本地客户端视图
答:1) 两个不同的JVM间,EJBHome和EJBObject用于响应远端客户端的调用。这样实现了位置无关,不管是不同JVM之间还是同一个JVM都能正常工作。
    2) 同一个JVM,EJBLocalHome和EJBLocalObject用于响应客户端调用。这种情况不存在网络传输,速度更快,但达不到位置无关。

5.  客户端与EJB的交互
答:1) 通过命名服务寻找home对象:
       a. EJB的home对象绑定于命名服务器,并通过JNDI访问。我们使用java.naming.InitialContext对象,提供一个JNDI名字给它去寻找我们的home接口。这是一个和我们EJB联系的逻辑名称。代码示例:
          InitialContext ctx = new InitialContext();
          Object objHome = ctx.lookup("ejb/itso/Customer");
          //Object objHome = ctx.lookup("java:comp/env/ejb/itso/Customer");
          CustomerHome home = (CustomerHome)javax.rmi.PortableRemoteObject.narrow(objHome, CustomerHome.class);
       b. JNDI名字是一个字符串,它代表了部署时对象的名字。这个名字可以是全局的EJB命名空间元素。
       c. lookup方法返回的是一个对象,你必须进行强制转换。
    2) 使用home对象创建或查找到EJB对象
       a. 一旦得到home对象,我们可以用它去确定我们的bean。对于实体bean,我们能够查找既存的实体bean或创建一个新的bean:
          Customer customer = home.findByPrimaryKey(aKey);
          或者
          Customer customer = home.Create(aKey);
       b. key是bean的主键,它可以是一个Integer(不能是原始数据类型);
       c. 对于没有状态的session bean, 我们只能调用create方法;
       d. 调用home的这些方法将会调用服务器中真正bean实例中对应的ejbCreate和ejbPostCreate, 或者ejbFindXxxx方法。
    3) 调用bean中的商业方法
       一旦我们得到了bean的句柄,我们便可执行它的任何的商业方法。
    4) 清除Bean
       我们可以选择去清除bean。对于实体bean,这意味着从数据表中删除记录。有二种移除bean的方法:
       home.remove(customer);              //调用home接口的remove方法
       或者
       customer.remove();                  //调用EJB对象(组件接口)的remove方法
       以上方法功能相同,它们最后都最终由容器去调用真正bean实例的ejbRemove方法

6.  远程和本地接口的区别与联系
答:远程接口                           |     本地接口
    Interface extends EJBObject        |     Interface extends EJBLocalObject
    Home extends EJBHome               |     Home extends EJBLocalHome
    Remote method calls                |     More efficient local calls
    Location Independent               |     Client and EJB in the same JVM
    Parms passed by value              |     Parms passed by reference
    Remote exception thrown On methods |     Regular Java Exceptions
    Use narrow() to cast               |     Use regular Java class cast

7.  本地接口强制转换
答:1) 在本地接口中,通过使用类的强制转换访问EJBHome的代码大为简化:
       InitialContext ctx = new InitialContext();
       Object objHome = ctx.lookup("ejb/itso/Customer");
       CustomerHome home = (CustomerHome)objHome;

8.  EJB框架(远程)时序图
答:Remote      Stub          ORB           Tie            EJB         EJB           EJB
    Client                                                 Object      Container     Implementation
    |             |           
    |business_Meth(Param)     
    |------------>|           
    |             |forward(Parm)
    |             |----------->|
    |             |            |business_Meth(Parm)
    |             |            |------------>|  
    |             |            |             |business_Meth(Parm)
    |             |            |             |------------>|
    |             |            |             |             |pre_Invoke()
    |             |            |             |             |------------>|
    |             |            |             |             |             |callback_Methos()
    |             |            |             |             |             |------------>|
    |             |            |             |             |             |Invoke_Context()
    |             |            |             |             |             |<------------|
    |             |            |             |             |             |             |
    |             |            |             |             | business_Meth(Param)      |            
    |             |            |             |             | ------------------------->|
    |             |            |             |             |             | Invoke_Context()
    |             |            |             |             |             |<------------|
    |             |            |             |             | post_invoke()             |          
    |             |            |             |             |             |callback_Method()
    |             |            |             |             |             |------------>|          
    |             |            |             |             |             |Invoke_Context()          
    |             |            |             |             |             |<------------|
    |             |            |             |             |             |             |

9.  EJB框架(本地)时序图
答:Local      EJB_Local   EJB_Local     EJB
    Client     Object      Container     Implementation

    |business_Meth(Parm)
    |------------>|
    |             |pre_Invoke()
    |             |------------>|
    |             |             |callback_Methos()
    |             |             |------------>|
    |             |             |Invoke_Context()
    |             |             |<------------|
    |             |             |             |
    |             | business_Meth(Param)      |            
    |             | ------------------------->|
    |             |             | Invoke_Context()
    |             |             |<------------|
    |             | post_invoke()             |          
    |             |             |callback_Method()
    |             |             |------------>|          
    |             |             |Invoke_Context()          
    |             |             |<------------|
    |             |             |             |

10. EJB类型
答:                 
                                    EJB
                                     ↑
                         |ˉˉˉˉˉˉˉˉˉˉˉˉ|
                   Synchronous               Asynchronous
                        ↑                        ↑
           |ˉˉˉˉˉˉˉˉˉˉˉˉ|        Message-Driven
        Entity                   Session
           ↑                       ↑
      |ˉˉˉˉˉ|             |ˉˉˉˉˉ|
     CMP        BMP        Stateless   Stateful

2004-10-19     星期二      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第五天)

WSAD预览

1.  WS家族
答:1) WSSD(面向网站开发者)
       . 用于开发Web Service、Service、JSP、Servlet、XML
       . Websphere应用服务器以及基本的团队开发支持
    2) WSAD(面向应用程序开发者)
       . 拥有所有WSSD的功能
       . 用于J2EE开发以及数据库应用程序
    3) WSAD Integration Edition
       . 通过使用J2EE集成框架,增加了企业综合应用

2.  WSAD工作台
答:1) 不是一个工具,不是一个产品,也不销售;
    2) 一个便携的、统一的工具平台和集成技术;
    3) 一个开源项目的基础;
    4) 公共的,容易使用的接口;
    5) 对于所有的工具具有同样的感官.

3.  WSAD术语
答:1) 透视图
       对同一个项目,依据角色提供不同的透视图。每一个透视图适合于特定的角色,提供该角色必备的工具以完成特定角色相关的工作。有Java、Web、J2EE、服务器、XML、数据透视图等。通过“Window->Preferences->Workbench->Perspective”可指定启动WSAD调用的默认透视图。
    2) 视图
       . 一个视图显示了特定的信息;
       . 一个视图可以显示于一个单个的窗格中,或几个视图能堆叠于一个具有标签的窗格;
       . 关于视图的信息更新立刻得到存储。
    3) 编辑器
       . 一个编辑器用于编辑或浏览资源;
       . 编辑器中的资源只有存盘后才能被保存。
    4) 在线帮助
       . 选择帮助菜单中“帮助->帮助菜单”;
       . 按F1键;
    5) 定义Java类的路径变量
       . 设置自己工作台时一个重要的任务是定义增加的类的路径变量。WSAD已创建了一组黙认的类的路径变量。
       . 具体设置方法“Window->Perferences->Java->Classpath Variables”

4.  Java编辑器属性
答:1) 代码格式
       工作台上的Java编辑器可根据个人喜好配置格式。修改黙认的代码格式步骤选择:Windows->Preferences->Java->Code Formatter
    2) Java编辑器首选项
       通过“Windows->Preferences->Java->Java Editor”可以修改编辑器的字体等。
    3) 组织导入
       你可以指定你希望Java编辑器处理导入语句排列的先后顺序,以及使用“*”号之前限定导定的数目。
    4) 重构
       在开发过程中,会经常碰到诸如重命名类、在不同包间移动类以及将一段代码做成一个单独方法之间的操作。重构用于描述这种变化。在传统编程环境下,这样的任务非常耗时并且容易出错。
       通过菜单“Window->Preferences->Java->Refactoring”可以指定重构工作的某些特性。
    5) 选择JRE
       通过“Windows->Preferences->Java->Installed”可以指定WSAD的JRE。
    6) 自动构建
       黙认情况下,当源文件被修改后自动被构建。当你完成一组大量的修改后没有值时,你希望手动构建。这种情况下,可以执行菜单“Windows->Preferences->Workbench”将“对资源修改执行自动构建”选项去除。
       WSAD中构建是增量式的,手动构建和重新构建将替代增量构建重新编译所有资源。

EJB项目的基本分析

1.  EJB建模
答:1) 对一个真实的应用,用例图描述了我们实际系统执行行为的轮廓。
    2) 在用例图中,用UML描绘了类和接口等。
    3) 你可以产生这些UML图形而不管是否是一个EJB应用程序。判断是否在应用程序中采用EJB是一个比设计更为架构上的行为。
    4) 当构建以及与你的EJB交互时确定最佳的行为和模式是一个设计级别的行为。
    5) 通过这种方式,设计模式将最终影响你是如何构建程序的行为。因此,EJB的设计受影响于一组设计原则。
    6) 实现商业逻辑是bean开发者的责任。

2.  何时使用实体bean?
答:1) 实体bean代表了业务中主要概念, 它们通常是我们系统中的名词。他们所代表的数据存储于持久的介质中,例如数据库。
    2) 在实体bean模型和数据库模型之间存在许多相似之处。在你系统的设计中,数据库中任何既存的东西都可以成为实体bean。
    3) 根据实际需求,我们可以选择实体bean类型为CMP或者BMP。

3.  何时使用无状态的会话bean?
答:1) 无状态的会话bean是纯粹的业务逻辑,为你的应用程序提供服务。他们能用于控制一个用户使用情形中的一系列步骤,虽然他们不记得交互过程中的任何状态。
    2) 在任何事件中,你系统中动词都是好的bean方法的侯选人。会话bean在实体bean的配合下执行持续行为要好于直接访问数据库。

4.  何时使用有状态的会话bean?
答:1) 也是处理商业方法的bean类型,但是能维护用户的会话状态。
    2) 因为他们能够记忆会话状态,他们能够提供无状态会话bean的一些额外功能。一个例子是在线购物车系统,它保存了你的订单信息,这样你能持续购物。
 
5.  何时使用消息驱动bean?
答:1) 无状态bean和消息驱动bean最主要的不同是他们被调用的方式。除此以外,对于处理纯粹的业务过程无状态bean和消息驱动bean是一样的。
    2) 值得一提的是,消息驱动bean能截取消息,然后指向一个普通的无状态bean进行处理。不同之处在于一个是同步调用,另一个是异步调用。这为你的系统提供了完整的双重服务模式。

6.  项目描述
答:1) 我们描述了一个非常简单的银行系统轮廓去帮助你理解我们的EJB建模;
    2) 我们定义了有关帐户的一些概念:客户、帐户以及交易;
    3) bank类定义了所有有关客户和帐户的行为,诸如:转帐、开户。一些行为是同步调用而另一些是异步调用。各种有关帐户的报表是需要的,并且在产生这些报表时,客户能维持一个绘话。

7.  EJB的侯选人
答:1) 实体bean:在我们系统中可能的实体bean是一些名词:客户、帐户、交易。
    2) 无状态会话bean:我们所描述的银行执行一些业务处理过程,诸如:转帐、开户。因此,银行是一个会话bean的好的侯选人,这代表了银行所能提供的服务。确信“银行”是无状态的是因为在我们例子中无须会话状态。
    3) 有状态会话bean:我们认为请求报表的处理过程可能是一个会话过程。对报表的请求处理将会是一系列的菜单,这用于一份报表。
    4) 消息驱动bean:对我们系统是否需要消息驱动bean的了解意味着对我们怎么选择并提供我们系统服务方式的了解。事实是,我们指定某些交互动作必须是异步的。我们可以允许事务被EJB客户端直接调用,或者通过发送消息不直接调用。对于后者,我们使用消息驱动Bean调用服务。

8.  银行模型
答:银行模型由一系列实体和关系组成。
    Customer: 银行的一个客户
    Account: 一个银行帐户。一个客户可能有多个帐户,一个帐户可能被多个客户拥有。一个帐户要么是核算(Checking)帐户,要么是存款(Saving)帐户。
    Checking: 一个银行帐户的子类;
    Saving: 一个银行帐户的子类;
    TransRecord: 银行交易过程中产生的交易记录。例如:存款,取消,或者二个帐户间的转帐。一个帐户可以有多个交易记录。

9.  模型关系图
答:                        Customer
                               ↑
                 relationship  | m:m
                               |         relationship
                               ↓<------------------------->TransRecord
                            Account        1:m                  ↑
                               ↑<------------------------------|  update create
                               |                                |
                      |ˉˉˉˉˉˉˉˉ|                        |
                      |   inheritance  |                  Money Transfer
                      |                |
                   Checking         Savings

10. EJB归类
答:1) 实体bean: Customer, Account, Checking, Savings, TransRecord
    2) 无状态会话bean: Banking
    3) 有状态会话bean: Reports
    4) 消息驱动bean: Transfer

11. 会话bean的facade
答:1) 一个通常的做法是使用一个facade位于保护了数据层的实体bean的前端,控制所有客户端的访问。在这种方式下,这个会话bean可将多个数据源访问集在一块作为一个单个的入口点进入业务层。这为我们系统的业务层和综合层中提供了一个清晰的分隔。
    2) 因为所有对实体bean的访问必须只在facade bean处发生,因此我们只能使用实体bean的本地端接口。这为系统提供了更高的效率。

WSAD的数据透视图

1. J2EE服务之JDBC
答:1) 提供了对多种关系型数据库的连通性,这种连通性与具体数据库无关;
    2) JDBC有点类似于ODBC,是基于X/Open SQL 调用层接口规范;
    3) 通过JDBC,你的Java应用程序或Java小应用程序可以动态地调用数据库;
    4) 在JDBC2.0中我们可以通过数据源对象访问数据源的一个连接的池子,使用连接池有下列优势:
       a. 它提高了性能。创建一个连接是费时的,而一个数据源对象一初始化就创建了一个连接池。
       b. 它简化了资源的配置。资源仅从数据源对象被配置,而不是代码中任意位置。

2.  数据源的工作步骤
答:1) 当一个Servlet或其它客户端想使用一个连接时,它从JNDI服务器上通过名称寻找一个数据源对象;
    2) Servlet或客户端向数据源对象请求一个连接;
    3) 假设数据源对象没有足够多的连接,它可以向数据库管理者请求更多的连接(只要没有达到最大允许的连接数);
    4) 当客户端完成了连接,它释放该连接。数据源对象然后将连接返回到更用连接池中。

3.  XMI和DDL
答:1) XML元数据交换接口(XMI)是一个对象组织标准接口,用于交换元数据信息;
    2) WSAD使用XMI格式存储数据库、表和模式的所有本地描述符。XMI文件能使用编辑器进行查看和修改;
    3) 当你导入一个即存的数据库模式,它是使用XMI格式存储的;
    4) 数据定义语言(DDL)是一种被关系统型数据库系统用于存储关于如何创建数据库对象的格式。WSAD允许你从XMI文件中产生DDL。

4.  数据透视图
答:数据透视图用于处理数据库、数据表和SQL声明,在该透视图中存在三种主要的视图:
    1) 数据库服务器视图
       显示了到数据库的活动连接并允许你创建新的连接,该视图与任何项目无关。连接可以钝化,这时没有数据库和数据表显示。通过选择连接右键菜单的“重新连接”可以重新激活连接。
    2) 数据定义视图
       显示了WSAD中当前既存的数据库模型,这些模型既包括通过数据库服务器视图导入的也包括在工作台上创建的。数据库模型存储相联系于WSAD项目,项目可以是一个简单的项目,一个有数据库访问的Web项目,或者是一个带有实体Bean的EJB项目。数据库定义视图是数据库对象的层次视图,它并没有显示这些定义是如何存储于真实的文件中。
    3) 导航视图
       在该视图中你可以看见代表数据库对象的本地描述符文件。每一个文件都有一个编辑器相联系于它。双击该文件可以打开与它所描述对象类型相适合的编辑器。这些对象类型可以是一个数据库、一个模式、或者一个数据表。

5.  使用数据库服务器视图
答:1) 你可以连接到既存的数据库并查看他们的对象。这些对象能导入WSAD并用于你的系统;
    2) 数据库服务器视图允许你过滤,显示部分模式或视图。你也可以使用数据库服务器视图产生DDL和XML模式。
    3) 重点:数据库服务器视图是只读的,在你能够编辑任何数据库项目之前,你必须将它们导入WSAD项目。

6.  创建数据库连接
答:1) 你应该为这个连接建立唯一的名字。假如需要可能要提供user ID和密码,以及你连接的数据库类型,JDBC驱动器可能用得到。对于DB2数据库有二种类型的JDBC:
    . COM.ibm.db2.jdbc.app.DB2Driver: 用于连接本地数据库或定义于本地的远端数据库;
    . COM.ibm.db2.jdbc.net.DB2Driver: 用于连接远端数据库;

7.  导入数据库
答:1) 创建一个简单的服务器项目例如ItsoProGuideDatabase去保存数据库对象;
    2) 通过以下步骤导入:
       . 在数据透视图的数据库视图中,选择要导入的数据库连接,导入文件夹;
       . 在“导入”对话框,点击“浏览”选择ItsoProGuideDatabase项目,然后点击完成。
    3) 在我们导入一个数据库,例如名称为EJBBANK,在数据定义视图中展开EJBBANK节点,相同的数据库对象显示出来。你现在能够打开这些对象相应的编辑器查看和修改他们的定义。
    4) 在导航视图中你能够注意到为数据库对象创建的一系列XMI文件(XMI提供了一种方式允许工作于对象技术的开发者通过网络去交换编程的数据)

8.  产生DDL文件
答:1) WSAD允许你为数据库对象产生DDL文件和XML模式文件;
    2) 产生一个DDL文件:在数据定义视图或数据库服务器视图中选择数据库对象,选择右键快捷菜单中的“生成DDL”命令。
    3) 你可以为数据库产生DDL,也可以为模式、或单个数据表。

9.  产生XML模式文件
答:1) 为一个表产生XML模式,你必须已将它导入进一个目录并且位于数据定义视图;
    2) 产生一个XML模式文件:选中一个数据表,点击右键快捷菜单中的“生成XML模式”命令。

10. 产生数据库对象
答:1) WSAD中的数据库创建并没有在数据库系统中创建一个真正的数据库。你必须导出DDL,然后使用适当的数据库工具创建对象或者在WSAD中提交DDL。
    2) 创建步骤:
       . 创建模式(它提供了对数据库对象的逻辑分类)
       . 表
       . 视图
       . 别名
       . 索引
       . 触发器
       . 结构类型

11. DB2 JDBC驱动器
答:DB2支持二种JDBC驱动器:
    1) COM.ibm.db2.jdbc.app.DB2Driver: 这是JDBC类型2驱动器,它使用的DB2客户端安装于应用程序所在的机器。当访问本地数据库或通过本地DB2客户端访问远端数据库时,数据库URL格式如下:
       jdbc:db2:databasename
    2) COM.ibm.db2.jdbc.net.DB2Driver: 是JDBC类型3驱动器,它使Java能访问远程的DB2数据源。你的应用程序将会同DB2客户端安装所在的另一个机器会话。数据库URL格式如下:
       jdbc:db2://hostname:port/databasename
       一般DB2的JDBC服务器端口为:6789,你另外需提供用户名和密码,例如:
       con = DriverManager.getConnection("jdbc:db2://localhost:6789/databasename","db2admin","db2admin");

2004-10-20     星期三      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第六天)

实体Bean

1.  何时使用实体Bean?
答:1) 实体Bean指商业或指定域的概念,它是你系统中的典型名词,指好的精度概念,例如客户和帐户;
    2) 他们通常表增存储于数据库中的数据。由于他们表示了持久于数据库中的数据,对bean结果的改变同时影响到数据库。

2.  为什么是实体Bean?
答:实体Bean允许对象化我们的数据,工作于代表数据的对象为什么优于直接访问数据库中的数据,存在很多好的理由:
    1) 工作于对象更容易得多,它们是一个系统中的可重用组件;
    2) 通过使用容器提供的服务,它使我们从一些基础功能的开发中解脱出来,这些功能包括:并发、事务、安全等。通过使用容器提供的服务,我们能专注于为bean和数据建立映射并为bean提供相应的商业方法而代替写SQL语句。

3.  为什么先开发实体Bean?
答:1) 实体Bean是最复杂的EJB类型;
    2) 通常,实体Bean是好的粒度对象,一般被其它粗粒度对象(例会话Bean)所使用,提供给我们的会话Bean一些现成的东西。
    3) 真实的世界中,?
    4) 我们并没有说所有的实体Bean都必须在你系统中任何其它部分之前被开发出来,但他们通常能够独立于你系统中其它部分被开发和测试。
    5) 一部分团队专注于实体Bean开发,另一部分团队专注于Servlet和JSP开发,这种情况很常见。

4.  实体Bean能幸免于服务器关闭
答:1) 实体Bean用于表示持久的对象,诸如客户和帐户。大多数情况下,表示实体Bean状态的持久数据存储于一个关系型数据库中。
    2) 对象的属性映射于一个或多个数据表中的记录。
    3) 由于状态存储于一个数据库中,一个实体bean的状态比请求、会话,甚至于容器的存活时间维持得更加长久。
  
5.  实体Bean的重要属性
答:1) 他们代表一个持久化的域对象;
    2) 他们支持并发访问;
    3) 实例被容器所管理(实例池),因而提供了可扩展能力;
    4) 他们能执行于一个安全的,对事务管理的上下文中。

6.  CMP实体Bean
答:1) 将产生持续能力的任务委派给EJB容器;
    2) 因此作为bean的提供者,我们不必为我们的实体Bean提供任何数据库访问的代码。我们让容器为我们做这些。我们唯一必须提供的是抽象的数据-对象映射:映射Bean中字段于数据库中,以及对应于这些字段的抽象方法;
    3) 容器知道数据要去被持续是因为这种映射关系定义于DD中。在部署的时候,执行相关操作的JDBC代码被容器自动产生;
    4) 当容器被真正部署时,相联系的数据源能被自动为bean和数据建立绑定;
    5) 按这种思路,CMP是一些相联系于数据的抽象类,但又没有提供任何访问数据本身的真正执行;
    6) CMP目标是使开发者以面向对象的思维工作,而不是以数据为中心的思路。通过分隔开发和持久化相关工作的另一个好处,开发者被解放出来而得以专注于商业逻辑。

7.  CMP中EJB1.1版本没有定义的内容
答:1) EJB1.1版本规范申明了CMP是必须的。但是许多本质的问题没有定义,诸如:
       . 映射于数据库模式的标准;
       . 用于定位bean的发现者的定义;
       . 如何指定实体bean细节之间关系的细节;

8.  EJB2.0中的新特性
答:通过提供一个标准的持久模型,EJB2.0规范实现了前面提到的一些问题。这种持久模型趋于模糊产品界线并成为所有EJB供应商的一个标准。规范提供:
    . 一个抽象的持久模式:这使CMP映射以一种抽象的方式被所有的供应商工具所执行;
    . EJB QL: 一个标准的查寻语言用于查找和定位bean,虽然它不是真正的SQL。它类似于SQL语言提供SQL功能的一部分。
    . 容器可控制的关系(CMR):标准化bean之间的关联方式,提供的关联类型有一对一,一对多,和多对多。也包括一部分抽象的持久模式。

9.  对CMP1.1的兼容性
答:1) EJB2.0版本提供了对EJB1.1版本的支持,因此用以前版本开发的EJB可无损地移殖于新的平台。

10. BMP实体Bean
答:1) 在BMP实体Bean中,EJB的开发者通过编写数据库调用代码或者其它持久存储的访问方式管理bean的持久状态。
    2) 这将适当管理bean的持久化状态的责任压在开发者身上,这样做需要理解回调方法的工作方式以及其它被容器调用的用以持久化服务的生命周期方法。
    3) 开发者的责任:
       . 当ejbLoad和ejbStore方法(bean的回调方法)被容器调用时存储和恢复bean的状态。
       . 通过ejbCreate和ejbRemove方法(bean的生命周期方法)创建、寻找以及移除bean。
    4) 大部分时间,BMP的开发者使用JDBC在他们的方法中直接编写持久逻辑。当然,其他技术也能被使用,诸如SQLJ或CICS事务。

11. CMP还是BMP?
答:对于BMP而言,开发者要做更多的工作,为什么还有人选它而不是CMP呢?仅管在EJB2.0中CMP有许多优势,但有还有一些事情CMP不能够 做到。一些将会影响你选择实体bean类型的事情包括:
    1) BMP比CMP开发复杂性以及维护性大得多。在其它方面相等的情况下,选择CMP能比BMP获得更好的可维护性;
    2) 一个容器给CMP的支持在数据源类型方面存在局限性。例如CICS就不支持当前CMP映射和调用模式。因此访问这些的时候就需要采用BMP;
    3) 复杂的查询对于EJB QL用于CMP中就不支持。例如,EJB QL规范支持Select和Join,但不支持时间的比较。
    4) 假如实体Bean之间的关系应该要建立时,CMP可能就是必须的。CMR拥有定义和管理实体bean之间关系的能力,并且能处理一些更复杂的关系。这种情况下,采用BMP是困难的。
    5) 对于CMP,容器会尽量优化SQL代码,因此他们将比你自己开发的BMP更富扩展性。BMP不适合大量性能敏感的应用程序。
    因此,除非你有真正的好的理由,还是采用CMP吧!

12. 主键--Bean的身份
答:1) 正如我们需要主键去唯一确定数据库中的记录,我们同样需要用主键去唯一确定我们的实体Bean。
    2) 实体bean的主键可以是任何Java原始包装类(Integer、Double)或基本的Java类(例如String)。他们被定义为单个字段主键,这个键值必须对应到我们定义的一个持久属性。
    3) 注意到原始的Java属性,例如int和float,必须被封装成主键类。
    4) 一个主键可以是任何我们开发的自定序列化类型,一个或多个字段必须映射到持久属性子集。
    5) 主键通过DD中属性指定。
    6) 主键是方法createXxxx的返回类型,它也是findByPrimaryKey方法的参数。
    7) 主键相等 + 同一个home接口 = 同一个Bean(可以使用isIdentical方法的component接口测试)。

13. 实体Bean结构
答:             
                 javax.ejb.EnterpriseBean
                          ↑
                          |
                   javax.ejb.EntityBean 
                          ↑
                          |     
               |ˉˉˉˉˉˉˉˉˉˉˉ|
        MyEntityCMPBean         MyEntityBMPBean
      (an abstract class)      (a concrete class)

13. 实体Bean结构
答:1) 通过DD中属性指定实体Bean的真正类型。
    2) CMP必须是抽象类,但是BMP必须是具体类。因为抽象类不能实例化,容器有责任产生具体的包含有真实属性的类。这在部署的时候基于定义于DD中的某些值产生。

14. EJB2.0中CMP和BMP
答:1) 抽象类/模式:EJB2.0中CMP是抽象类,尽管它们在EJB1.X中是具体的类;
    2) BMP依然是具体的类;
    3) 抽象类的映射定义在XML格式的部署描述符文件中;
    4) 部署描述符中的映射被定义为抽象的持续模式。

15. bean和容器之间的协议
答:理解了一个bean开发者开发一个功能丰富的bean时所要干什么,也就理解了bean的回调和生命周期方法,以及bean和容器之间的协议是怎么形成的。

16. 实例池
答:1) 实体bean是一种能产生实例池的企业bean类型, 并且能被EJB容器重用;
    2) 实例池是容器的一种服务,允许容器重用bean实例,这相对于每一个请求每次产生一个bean的实例。这是容器对性能所做的最佳化操作之一;
    3) 这适合于一个可扩展性的环境,因为池的尺寸在需要的时候可以增加;
    4) 将对象移进池中然后激活他们对于理解实体bean是一个好的开始。

17. 实体bean的状态
答:1) 实体bean有三种状态:no-state, pooled, and ready;
    2) 假如bean实例还没有创建,它处于no-state状态;
    3) 一旦实体bean被创建但还没有和一个EJBObject相联系,它处于pooled状态;
    4) 当实体bean和EJBObject相联系后,它从pooled状态进入ready状态;
    5) 这些状态改变是重要的,因为每个状态的改变都触发容器去调用对应状态改变的回调方法。作为一个开发者,你应该理解这些改变以确定为你bean的回调方法提供适当的逻辑。

                                              ejbCreate()
                                       |ˉˉˉˉˉˉˉˉˉˉˉˉ|
                setEJBContext()        |                        ↓
       No State-------------------->Pooled------------------->Ready
               <--------------------  ↑  <------------------   |
                unSetEJBContext()      |     ejbPassivate()     |
                                       |________________________|
                                               ejbRemove()
                |_______________|          |_______________|
                  bean created/         Associated/disassodated
                end-of-life cycle          with an EJB Object

18. 回调方法
答:1) setEntityContext():当bean被容器调用第一次加入池中时,该方法应该为这个bean捕获一个EntityContext的引用。
    2) unSetEntityContext():当bean从池中移除时该方法被容器调用,这通常是服务器关闭的时候,这个方法应该清除所有资源。
    3) ejbCreate():当一个客户端通过home接口创建一个实例的时候调用。
    4) ejbActivate():当bean从池中调出服务一个请求的时候调用。
    5) 这些方法为bean的使用作准备,诸如初始化非持久字段。
    6) ejbRemove():当一个客户端调用一个实体bean实例的时候调用。
    7) ejbPassivate():当bean被容器释放回池中调用。
    8) 这些方法被用于设置所有持久字段为空,因此下一个pooled bean实例的用户拥有一个崭新的bean实例。大多数时候这些方法是空的。


2004-10-21     星期四      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第七天)

实体Bean

19. 实体bean的生命周期
答:1) 我们可以看见实体bean在移进实例池的时,开始了他的生命周期。这发生于服务器启动的时候。在这个时刻,它是一个未初始化的bean,它等待着和一个EJBObject相联系,进而响应客户端请求。
    2) 创建实体bean:对于实体bean而言,这不仅意味着创建一个新的bean实例,也意味着在相对应的数据库中插入一个新的记录。这项活动通常对应于一个数据库数据表记录的insert。
    3) 寻找既存的实体bean: 这指寻找一个状态存储于数据库中,尚未和EJBObject相关联的bean。相应的容器方法在这里会被调用,这项活动通常对应于一个数据库数据表记录的select。
    4) 使用实体Bean:一旦得到一个bean的实例,当客户调用商业方法时,容器回调发生。根据访问的类型,这些活动通常对应的数据库数据表记录的select和update。
    5) 移除实体Bean:对于实体Bean,这意味着从对应数据库真实地删除一个记录。这项活动通常对应着数据库数据表记录的delete。

20. 创建一个实体Bean时的生命周期过程
答:1) 生命周期方法定义
       . 对于创建实体bean的生命周期方法是:ejbCreate、ejbPostCreate和home接口中的create方法。
       . 通过不同signature或后缀你可以有多个创建方法。后缀可以用于区别拥有相同signature的方法。
    2) 创建方法
       . home接口中的创建方法必须对应于bean class中的ejbCreate和ejbPostCreate方法。
       . home接口create方法返回一个组件接口的引用,但bean class的ejbCreate方法必须返回一个主键。
       . home接口的create方法和bean class的ejbCreate方法必须抛出CreateException异常。当bean已存在时,会抛出CreateException异常的子类DuplicateKeyException。
    3) 我们的责任
       在ejbCreate方法调用时会产生二个结果:
       . bean的状态必须由开发者完成初始化,不管它是CMP还是BMP。
       . 必须向数据源中插入真实的数据。对CMP而言,容器已为你做好。而BMP需开发者手动编写插入逻辑。
    4) 实体bean创建时的生命周期时序图
       a. setEntityContext:将一个bean和环境信息关联起来,一旦这个方法被调用,Bean就可以访问有关它的环境信息。
       b. create: 客户端调用创建方法创建一个bean的实例。
       c. ejbCreate: 准备向数据库插入数据。
       d. Primary key: ejbCreate方法返回主键给容器以便它能构建一个新的EJBObject。
       e. newInstance: 一个真实的EJBObject实例将会返回给客户端。
       f. ejbPostCreate: 我们现在有一个主键和一个EJBObject。通过EJBObject,我们能访问bean以及操作CMR字段。
       g. INSERT:执行数据库的insert操作。
       h. return EJBOBJECT:返回客户端EJBObject,bean现在为服务客户端的请求作好了准备。

21. 寻找一个既存实体Bean时的生命周期过程
答:寻找一个实体bean就像数据库中执行一个select操作。当我们想要寻找一个既存的实体Bean时,我们调用find方法。实体Bean必须指定一个寻找方法:findByPrimaryKey。调用findByPrimaryKey方法后返回给客户端一个EJBObject或EJBLocalObject。
    1) 我们的责任
       . CMP类型的实体bean class没有直接定义findByPrimaryKey方法,仅在home接口中定义。部署描述符中的主键和实体bean存在联系,因此容器在部署bean的时候能够产生寻找方法去持久化Bean class。
       . 对BMP而言,你必须在ejbFindByPrimaryKey方法中编写select逻辑:取得数据库连接、手工编写SQL语句并执行select。
    2) findByPrimaryKey的生命周期时序图
       a. setEntityContext:将一个bean和环境信息关联起来,一旦这个方法被调用,Bean就可以访问有关它的环境信息。
       b. find: 客户端调用相应的find方法。
       c. select: 执行数据库的select操作。
       d. Primary Key: ejbFind方法将得到的主键返回给容器,让它构建一个新的EJBObject。
       e. return EJBOBJECT:返回客户端EJBObject,bean现在为服务客户端的请求作好了准备。

22. 使用一个实体Bean时的生命周期过程
答:一旦我们创建或寻找到一个实体Bean、创建了EJBObject的引用,EJB的客户便能够调用实体Bean的商业方法。调用实体Bean的商业方法和数据库操作中的select/update类似。这个过程称为同步对象数据到后台数据库。同步使数据库中数据和实体Bean中的状态数据相等。
    1) ejbLoad方法:
       a. 只有一个ejbLoad方法,这是一个回调方法;
       b. 同步数据库中数据到bean class中时, 如有必要可调用这个方法;
       c. 这在大多数时候很可能会触发一个select操作;
       d. 当客户端请求使用bean class、激活它时,ejbLoad被触发,然后bean class进入ready池。
    2) ejbStore方法:
       a. 只有一个ejbStore方法,这是一个回调方法;
       b. 同步bean class中数据到数据库时, 如有必要可调用这个方法; 
       c. 这在大多数时候很可能会触发一个UPDATE操作;
       d. 当bean class不再被客户端使用、容器决定将这个处于ready状态的bean class实例移进实例池中时ejbStore方法被触发。
    3) CMP与BMP中的ejbLoad
       a. CMP中的ejbLoad: 在数据从数据库中同步到bean class后调用ejbLoad。这为开发者提供一个机会处理一些数据层的操作,但真正编码的时候极少。
       b. BMP中的ejbLoad: 开发者必须在这个方法中直接编写select逻辑去同步bean class和数据库。
    4) CMP与BMP中的ejbStore
       a. CMP中的ejbStore: ejbLoad调用刚好发生在数据从bean class同步到数据库后。这为开发者提供一个机会处理一些数据层的操作,但真正编码的时候极少。
       b. BMP中的ejbStore: 开发者必须在这个方法中直接编写update逻辑去同步bean class和数据库。
    5) 使用实体bean时的生命周期时序图(客户端已通过create或find方法得到bean的引用)
       a. Business method:客户端通过组件接口调用一个商业方法;
       b. Container:这个动作触发实例池中一个bean实例被装载;
       c. ejbActivate: 这个调用使容器激活实例池中一个bean实例;
  CMP: d. select:将数据库中数据同步到bean class中来;
       e. ejbLoad:刚好在select执行之后被调用;
  BMP: d. ejbLoad:
       e. select:

       f. Business method:实际bean实例的方法被调用;
       g. Returned:具体方法的返回结果。
    6) 钝化实体bean时的生命周期时序图
       a. Container:触发一个bean实例移回实例池中,它将bean实例从EJB object的联系中断开;
       b. ejbPassivate:这个调用使容器钝化bean实例回实例池中;
       c. ejbStore:刚好在UPDATE执行之前被调用;
       d. UPDATE:将bean实例的数据同步回数据库中。
       没有客户端直接操作于bean。

23. 移除一个实体Bean时的生命周期过程
答:一旦我们创建或找到一个实体bean,为EJBObject创建了一个引用,EJB客户端就可以选择remove它。调用bean实例的remove方法和底层数据结构的DELETE操作很相像。
    1) 移除实体bean的方法是ejbRemove。在容器移除bean class相联系的EJB object之前调用这个方法。假如在移除一个bean的时候发生错误会抛出RemoveException异常。
    2) 我们的责任:
       CMP ejbRemove: ejbRemove方法刚好发生在数据库删除之前,大多数情况下不会编写代码。
       BMP ejbRemove: 必须在这个方法中直接编写DELETE逻辑。
    3) 移除一个实体Bean时的生命周期过程(客户端已通过create或find方法得到bean的引用):
       a. remove: 客户端调用组件接口中的remove方法;
       b. Container: 作些准备;
       c. DELETE: 数据库中的记录被删除;
       d. ejbRemove: 容器将bean实例移进实例池。

24. 抽象的持久模式映射
答:抽象的持续化模式允许我们指定两件事情:CMP(container-managed persistence data-to-object appings)和CMR(container-managed relationships)。这和一个数据库模式被定义的过程很像:数据表、字段和数据表间关系。在EJB抽象持久模式中,这些对应于实体bean, CMP字段和CMR字段。

25. 持久字段
答:1) 持久字段是我们实体bean中被定义可持久化的字段,它们可以是原始或可序列化的Java类型.每个持久字段通常对应于数据库中一个字段。
    2) 不同于BMP,CMP没有在bean中实际定义这些字段,但定义了这些字段的抽象getter/setter方法。
    3) 每个实例bean在EJB的DD中必须有一个对应的条目,bean的持久字段定义于其中。
    4) 容器在部署的时候根据定义在DD中的映射产生实际的SQL代码。它使用bean class中的映射确定字段的实际类型。

26. 建设一个实体bean
答:当我们构建一个实体bean时,我们关心:
    1) Bean class:它必须包含持久字段的getter/setter方法,并且实现bean的回调方法、组件接口方法,以及任何home接口中的生命周期方法;
    2) home interface:定义了bean的生命周期方法;
    3) Component interface:定义了bean的客户端视图以及对应的商业方法;
    4) DD:XML格式的部署描述符文件。
       Container     //持久化类型为CMP
       Bean          //持久化类型为BMP

2004-10-22     星期五      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第八天)

会话Bean

1.  介绍
答:1) 实体bean允许我们对象化共享的数据,这是持久化存储的,通常是存在一个数据库中。
    2) 容器以一种安全的方式管理了共享数据的并发访问;
    3) 会话bean可以直接访问位于数据库中的数据(不建议这样做)去手动地完成部分任务,或者通过实体bean访问数据。

2.  会话bean的一些概念
答:1) 会话bean是非持久的实体bean;
    2) 会话bean存在二种类型:有状态和无状态;
    3) 会话bean可用于协调实体bean的工作,提供访问实体bean的上下文;
    4) 例如,两个银行帐户(用实体bean表示)之间的转帐可用一个会话bean实现。这样一个转帐的会话bean应首先找到二个帐户实体bean的实例,从一个帐户中减掉金额并加到另一个帐户中。

3.  会话bean类型
答:1) 存在二种类型的会话bean:有状态和无状态;
    2) 在结构上,这些bean类型看上去是相同的,区分它们在于被调用的方式,是否在bean和客户端间存在会话状态;
    3) 有状态的会话bean表征了单个客户的会话状态,在整个会话过程中都是可用的;
    4) 无状态的会话bean并未分配给一个特定的客户端,可在多个客户间重用;
    5) 二种类型会话bean的主要不同在于容器是怎样管理它们的生命周期;
    6) 无状态的会话bean可放于实例池中并且在需要时被许多不同的客户端重用;
    7) 相反,有状态的会话bean不存在实例池,对于每个bean方法,容器必须得到相同的bean class实例;
    8) 不同类型的会话bean,bean的开发者责任不同。

4.  无状态会话bean
答:1) 无状态会话bean没有保持一个客户端的会话状态;
    2) 它们可放于实例池中,进而可被容器重用以服务于多个客户;
    3) 对于客户端而言,它们都是相同的;

5.  没有会话状态
答:1) 无状态会话bean为单个方法调用保存状态,这也就是说它们没有会话状态;
    2) 一个无状态会话bean的每个方法调用后,容器释放bean class实例回实例池,这时bean实例变得可用,因而它能服务于一个新的请求;
    3) bean没有为前一个调用方法的客户端保存记忆。即使是同一个客户端调用相同EJBObject的其它方法, 也不能保证会调用相同的bean class实例;
    4) 当同样的客户端调用另一个方法,一个不同的无状态会话bean class实例可服务于这个新的请求。例如:假如一个客户端调用一个无状态会话bean的方法A,然后立即调用同一个bean的方法B,这些请求可被不同bean class实例所服务;
    5) 一个无状态会话bean没有保存一个客户端行为的任何状态,这是一个记忆的重点。因为在开发无状态会话bean时人们通常所犯错误之一就是尝试在多个方法调用间保存数据。

6.  无状态会话的一致性
答:1) 所有从相同home对象产生的实例在客户端看来都是相同的,容器能使用任何一个可用的使用满足客户端的请求;
    2) 假如一个客户端拥有相同home对象产生的无状态会话bean的二个不同句柄, 组件接口的isIdentical方法通常返回真。

7.  实例池
答:1) 实例池提供了一个可扩展的环境,因为池的尺寸在需要的时候可以增加:加大容器缓存的尺寸,增加内存或提供更多的机器。
    2) 记住EJB客户端从来不直接处理bean实例,他们通常是从容器通过EJBOBject处理。容器对于实例池是开放的,然后在需要的时候重用bean class的实例并对客户端隐藏实现的具体细节。


2004-10-25     星期一      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第九天)

8.  有状态的会话bean
答:1) 有状态的会话Bean保持了一个客户端的会话状态;
    2) 他们必须从属于一个并且只能从属于一个客户端,事实上,并发访问同一个有状态的会话bean会导致容器抛出异常;
    3) 有状态的会话bean不存在实例池,因为在整个会话期间容器必须保持一个有状态的会话bean实例服务于相同的客户端;
    4) 通过使用钝化和激活方法,容器可以选择去优化访问有状态的会话bean。

9.  会话状态
答:1) 一个有状态的会话bean持有跨越多个方法调用的会话状态;
    2) 一个会话状态是客户端和应用程序间的交互。在任何需要的时候, 这种交互通常要求客户端和应用程序间的会话数据进行存取和访问。
    3) 一个会话的例子是一个保存了客户想购买的所有产品的购物车。这些数据也称为会话数据;
    4) 来个客户端的所有方法调用被同一个bean服务;
    5) 在会话期间,bean持有其服务客户端的会话状态。在一些更为高级的操作里,会状态状态中也许保持有开放的资源,例如打开的数据库连接;
    6) 一个有状态的会话bean的会话状态存储于bean的实例字段中;
    7) 大多数情况下,这些数据必须可序列化。
    9) 容器必须分配给每个方法调用相同的有状态会话bean的实例;
    10)每当一个客户端调用home接口的create方法一次,就产生一个新的实例;
    11)你可以保存数据于有状态的会话实例中,因此这些数据在下一个方法调用中依然有效。

10. 有状态会话bean的身份确认
答:1) 所有从相同home接口创建的有状态会话bean实例对于客户端看来是唯一的;
    2) 假如一个客户端持有从相同home接口创建的两个不同有状态会话bean实例,组件接口的isIdentical方法通常返回false。

11. 钝化和激活
答:1) 当实体bean从实例池中借出相联系于一个EJBObject的时候,实例bean便经历了激活过程;
    2) 激活的目的是为实体bean和真实数据相联系做些准备,并允许任何初始化的行为发生;
    3) 有状态会话bean同样存在钝化和激活过程,不过它的目的和实体bean有轻微的不同;
    4) 当有状态会话bean的状态存于次要的存储空间时便发生钝化过程,这样容器便有更多的资源可用;
    5) 这通常在bean空闲多时发生;
    6) 钝化后,被bean实例所占用的内存可被重新申请;
    7) 假如这个bean被以前的那个客户端重新请求,它又被激活回容器的内存;
    8) 容器在必要的时候钝化和激活有状态实体bean以管理它的资源;
    9) 容器不能钝化处于一个事务过程中的实例,应该先完成事务过程。

12. 序列化
答:1) 为了使容器高效管理大量的bean实例,它能使实例撤离内存并存储于持久化的存储空间中;
    2) 容器使用对象序列化转换bean的状态为二进制流或二进制的大对象(BLOB),然后将序列化的数据写入持久化的存储空间中。正如我们先前提到的,这个过程被称为钝化;
    3) 当这个bean被再次调用,容器创建一个新的实例并使用钝化过程存储的数据初始化它。这个过程称为激活;
    4) 因此,假使会话bean包括一些必须在多个方法调用期间被存储的会话状态,这种会话bean指有状态的会话bean;
    5) bean的提供者有责任确保状态数据可被钝化和激活;
    6) 不是所有的有状态会话bean通过钝化结束生命周期,因为容器不能确定资源是否需要优化;
    7) 当客户端不再需要bean的时候,它们直接被移除。

13. 有状态和无状态会话bean的比较
答:当开发企业级的应用程序时,很多时候开发者必须确定采用什么类型的会话bean, 这种判断通常不简单。下面是一些选择原则:

    有状态                          | 无状态
    -------------------------------------------------------------------
    可在多个方法间保持状态          | 不能在多个方法间保持状态
    可为多个方法或事务的商业过程服务| 只用于单个请求、单个方法调用
    可记住客户端历史                | 忽略客户端历史或状态

    1) 在决定采用哪种类型的会话bean时,请先回答下面二个问题:
       . bean需要知道客户端执行商业逻辑的状态吗?
       . 在方法调用时,bean需要保持状态吗?
    2) 假如上面二个问题的答案都是肯定的话,你应该考虑使用有状态会话bean;
    3) 假如二个问题都是否的话,则使用无状态bean更有利于你的应用程序。
    4) 无论如何,在你想使用有状态会话bean时,请考虑以下两点:
       . 假设发生故障(例如网络或系统故障,系统重启),状态将会丢失;
       . 有状态会话bean不容易再生,这在集束环境下导致性能低下。
    5) 只有在绝对有必要时,才选择使用有状态会话bean,因为他们需要多得多的系统资源;
    6) 假如一个商业逻辑需要使用有状态的会话bean,例如购物车,这时侯可以考虑它们;
    7) 需要记住的是开发者必须设法确保这些bean的生命周期, 诸如创建、使用、移除,已清楚的说明,这样工作流才能通过该bean被表达。

14. 会话bean的结构
答:1) 有状态和无状态bean实现了相同的接口:javax.ejb.SessionBean;
    2) 会话bean的实际类型是申明于部署描述符中。部署描述符的条目的内容要么是Stateful,要么是Stateless;
    3) 有状态和无状态bean的物理结构几乎是相同的。

                     javax.ejb.EnterpriseBean
                               ↑
                            Account
                               ↑
                      javax.ejb.SessionBean
                               ↑
                    |ˉˉˉˉˉˉˉˉˉˉˉˉ|
          MyStatefulSessionBean    MyStatelessSessionBean

15. 回调方法
答:1) 忽略会话bean的具体类型,bean类必须实现回调方法(ejbActivate、ejbPassivate)。容器使用这些方法去实际管理bean。
    2) bean也必须实现home接口中的生命周期方法,特别是create和remove。这些方法定义了基本的bean-container协议。

16. ejbCreate
答:1) 一个会话bean必须至少要有一个ejbCreate方法;
    2) 对于无状态会话bean,只有一个没有参数的ejbCreate方法;
    3) 有状态会话bean可以有多个ejbCreate方法,每个方法定义了一个唯一的方式去初始化会话bean的会话状态;

17. bean-container协议
答:1) 理解了实现一个意义丰富的会话bean时开发者的责任,也就理解了bean的回调方法和生命周期方法以及bean-container协议是如何生效的。
    2) 协议不依赖于会话bean的类型, 这里我们描述bean-container协议的基本概念:无状态会话bean的实例池、有状态会话bean的激活和钝化

18. 无状态会话bean的状态
答:1) 无状态会话bean有两种状态:no state和ready pool;
    2) 本质上,假如bean的实例还没有创建,则它处于no state状态;
    3) 一旦容器决定需要一个无状态的会话bean,它进入ready状态。bean将会保持这种ready状态直至容器不再需要它;
    4) 实例池中的bean没有和一个EJBObejct相联系的事实并不意味着它不是一个bean实例;
    5) 这是一个ready-and-waiting池态实例,当它处于ready状态,这时如果一个客户端需要bean的服务,容器将会确使bean和一个EJBObject 相联系。
    6) 客户端调用无状态会话bean的create和remove方法,但是它真正执行取决于容器的生命周期方法。
    7) 来自于客户端对create的调用是一种通知容器从池中分派一个bean实例的方式。真正的bean实例的创建方法可能早已经发生了。
    8) 客户端对无状态bean实例create方法的调用会创建新的EJBObject实例(实现了remote接口)。一个remove调用会移除EJBObject实例,而不是真实的会话bean实例。
    9) 容器会保持足够的实例(不超过容器的最大许可数)服务于当前的客户端。
    10)工作量并不以实际的客户端数目进行衡量,因为客户端仅在每一个方法调用时需要会话bean。
    11)在一个池中实际需要的无状态会话bean通常远远小于实际客户端的数量。

12. 有状态会话bean的状态
答:1) 有三种状态:no state, In Use, Passivated
    2) 假如bean实例还没创建,它处于no state。
    3) 一旦客户端需要有状态会话bean,它将调用主接口实例的create方法,这将使bean移入In Use状态。
    4) 在客户端和bean保持会话的整个期间,bean都将保持ready状态。
    5) 当bean处于使用状态,它可以阶段性地被钝化。
    6) 这些状态转换很重要,因为每个状态的改变会触发容器调用状态改变相应的回调方法。
    7) 作为一个开发者,你必须理解这些转换以便应用适当的逻辑于这些回调方法。

13. ejbPassivate
答:1) 当容器决定钝化bean时该方法被调用。在钝化的时候,它将序列化bean的状态到次要的存储空间并收回其占用的内存。
    2) 该方法刚找在要序列化之前被调用,这提供一个机会给开发者以确信bean的状态能被序列化。
    3) 客户端不能控制这个方法的发生,容器使用适当的算法决定哪些bean适合钝化。

14. ejbActivate
答:1) 当一个客户端调用处于钝化状态的bean时,该方法被调用。
    2) ejbActivate方法刚好发生在bean被反序列化后,这提供给开发者机会以重新初始化需继续bean操作的任何数据。

15. 创建/移除无状态会话bean时的生命周期
答:1) 容器决定创建bean:容器在启动或者在要分配更多的bean到实例池时会创建一些bean的实例。通常,当服务器第一次启动时创建一个bean的实例池。
    2) newinstance: 容器初次创建bean class的新实例。
    3) setSessionContext: 容器设置那个bean的会话上下文。
    4) ejbCreate: 允许bean的初始化操作发生。
    5) ejbRemove: 容器决定将bean从内存中收回以保存资源,允许清除bean资源的操作发生。

16. 使用无状态会话bean时的生命周期
答:1) create: 客户端调用home接口的create方法,这导致容器将池中的一个实例与客户端相联系;
    2) newInstance: 产生EJBObject;
    3) ejbObject: 返回EJBObject给客户端;
    4) Business method: 客户端通过EJBObject调用bean的商业方法;
    5) EJBObject调用池中bean实例的方法。EJBObject仅在商业方法期间和bean实例相联系。

17. 有状态会话bean的生命周期
答:. Create an stateful session bean: 这是一个客户端通过调用home接口发起的行为,调用创建一个新的有状态会话bean。
    . Finding an existingstateful session bean: 这个调用将导致客户端重新和一个客户端联系。
    . Using and stateful session bean: 客户端调用既存bean的方法。
    . Passivating/activating a stateful session bean: 这发生于容器决定钝化和激活会话bean的时候。
    . Removing a stateful session bean: 这也是一个客户端发起的行为,调用remove方法。

18. 创建有状态会话bean时的生命周期
答:1) create: 客户端调用home接口的create方法,这导致容器开始构建bean实例和EJBObject。
    2) newInstance: 有状态会话bean的一个新实例被创建。
    3) setSessionContext: 设置容器的上下文。
    4) ejbCreateXXX: bean实例对应的ejbCreateXXX方法被调用,这个方法可以初始化会话bean的状态。
    5) newInstance: EJBObject被创建。
    6) ejbObject: 返回EJBObject给客户端。

19. 查找一个既存会话bean
答:1) 一个有状态会话bean在被客户端移除或在容器中时间到了之前一直保持活动;
    2) 一个客户端也许需要访问一个既存的有状态会话bean。实体bean通过finder方法去定位既存的实例bean。一个有状态会话bean的身份,不是通过主键或其它唯一的标识符确认。因此它们并非通过finder方法。有状态的会话bean和一个客户端相联系,客户端能通过组件接口的句柄获得对bean class的访问。这个句柄能序列化并在以后的时间用于重新查找bean。
   
20. 查找一个既存会话bean时的生命周期
答:1) get Handle:客户端得到能被存储的(例如存在HttpSession中)句柄对象。一个新的句柄对象产生。
    2) getEJBObject: 句柄的getEJBObject方法被调用。
    3) finds bean: 容器将EJBObect重新和客户端相联系。
    4) ejbObject:返回EJBObject给客户端。

21. 使用一个有状态会话bean时的生命周期
答:1) Business method: 客户端调用EJBObject的商业方法;
    2) Business method: EJBObject将调用提交给bean class。

2004-10-26     星期二      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第十天)

22. 钝化和激活一个有状态会话bean
答:1) 当容器要释放一些容器资源的时候,有状态会话bean便会发生钝化;
    2) 当一个客户端调用一个已钝化bean的相关操作这时会发生激活;
    3) 钝化和激活都是容器管理的操作;

23. 钝化和激活一个有状态会话bean时的生命周期        
答:1) Passivation trigger: 通过某些算法,容器确定钝化哪个bean;
    2) ejbPassivate: bean的ejbPassivate方法被调用,为序列化做好准备;
    3) State is written to secondary storage: bean的状态写入一些辅助存储器,诸如数据据或文件目录;
    4) Business method: 客户端调用bean的商业方法;
    5) State is rebuilt from secondary storage: 重建bean的状态;
    6) ejbActivate: 调用ejbActivate去重新初始化任何必须的非序列化数据;
    7) Business method: 执行bean实例的真实商业方法。

24. 移除一个有状态的会话bean时的生命周期
答:当一个bean时间期满的时候,容器会决定移除bean,无论它是处于passivated还是ready状态。
    1) remove: 客户端开始一个remove操作,要么是调用EJBObject的remove方法,要么是调用EJBHome的removeHandle。两种方法产生相同的结果。
    2) ejbRemove: 调用ejbRemove方法给bean一个最后的机会清除任何打开的资源。
    3) timeout: 有状态的会话bean当其过期了也会给容器移除,这时不管它是passivated还是ready状态。

25. 构建一个会话bean
答:当我们构建一个会话bean,我们指的是构建bean class, home和component接口,以及DD:
    1) Bean class: 必须包括回调方法,实现组件接口方法以及任何home的生命周期方法,不同类型的回调方法实现于不同类型的会话bean(例无状态会话bean不存在钝化和激活,因此ejbActivated()和ejbPassivated()方法空实现);
    2) Home interface: 定义bean的生命周期方法,会话bean除了create和remove外,没有find以及其它主接口方法;
    3) Component interface: 定义bean的客户端视图以及对应的商业方法;
    4) DD:bean的XML格式的部署描述符。

26. 部署描述符
答:. : 这个可选条目允许我们为其它EJB定义一个本地引用;
    . 通过定义本地引用,EJB可被本地的JNDI名域服务器寻找得到这个bean;

27. 会话bean设计和构建的最佳习惯
答:1) 不要在无状态会话bean中存储会话状态:  这几乎就是无状态会话bean的定义,但是它值得一再重复;
    2) 一个方法的执行不应该依赖于任何先前的客户端或会话状态;
    3) 使用ejbCreate方法初始化无会话状态的会话bean;
    4) 使用ejbRemove方法清除任何无状态会话bean打开的资源;
    5) 在无状态会话bean中不要实现ejbPassivate和ejbActivate逻辑,无状态会话bean不存在钝化和激活,这些方法不会被调用;
    6) 不要从多个客户端调用一个会话bean,确信你的逻辑禁止有状态会话bean被二个不同客户端调用;
    7) 确信你的bean不会进入循环调用,bean的再进入是被禁止的;
    8) 异常处理:适当的异常导致bean从内存退出;
    9) 保持bean存活期相对地短:虽然会话bean能在一个客户端会话期间存在,但这个会话不应该永远地存在(例如一个星期);
    10)尽量使客户端的会话状态有限以及可管理。例如,一些类型事务的长度。
    11)假如必要,将一些大的,长时间运行的会话bean分为更多数量,短时间运行的bean以便管理。
    12)会话bean应该是一些粗粒度的商业处理过程,例如存款和取款。尽量隐藏细粒度活动:通过一个会话bean不要暴露一个实体bean的所有方法。
    13)session facade: EJB的session facade模式为服务器端组件提供了一个稳定的,高水平的网关。一个EJB session facade对客户端隐藏了实体bean的接口。所有对实体bean的访问必须通过会话bean的方法。
    14)在EJB2.0中实体bean只定义了本地端接口。会话bean定义了本地和远端接口。因为所有对实体bean的访问是通过和实体bean位于同一服务器的会话bean的方法。

28. 寻找bean的主接口
答:1) 这里显示了如何查找一个会话bean的主接口;
    2) 因为我们使用远端接口,我们需要在InitialContext的look up方法后调用PortableRemoteObject的narrow方法;
    3) 通过home对象我们可以寻找到我们bean的远端组件接口。
    InitialContext ctx = new InitialContext();
    Object objHome = ctx.lookup("itso/BankingJNDIName");
    BankingHome bankingHome = (BankingHome)javax.rmi.PortableRemoteObject.narrow(objHome, BankingHome.class);

实体Bean的高级部分

1.  介绍
答:1) CMR(EJB container-managed relationships): Relationships是一种定义实体bean之间联系的一种方式。容器内建了对EJB关系的支持;
    2) EJB间的遗传:遗传是实体bean继承其它bean的一种能力,在IBM的产品中,例如VisualAge for java和WebSphere,还是EJB1.1便提供了对这种能力的支持;
    3) EJB客户查询方法:查询方法是home中用于定位实体bean的任何方法,例如findXxx(称为finder方法)和selectXxxx(称为select方法);
    4) 我们所谈到的CMP,容器基本一种抽象的查询语言——EJB QL(SQL的子集)——负责产生实际的数据库代码;
    5) 客户的finder方法对于CMP和BMP均是可行的,但CMP对于QL语言更有优势。

2.  CMR(EJB container-managed relationships)
答:1) 实体-关系数据库模型图表简称为ERD,ERD定义了关系数据库中表间的关系,通常这些关系是通过主外键声明表示。
    2) 一个数据库中的外键匹配于另一个数据库中的主键,这样便形成一个关系。
    3) 为实体bean定义关系的过程有点像关系数据库中定义ERD。
    4) 在实体bean中,我们处理的是对象,不是表,对象中包含了数据和方法。因此,实例bean的关系定义必须超越数据模型。
    5) CMR被定义为实体bean之间的集合和合成关系。
    6) 重点:一个表中的外键是实体bean关系的先决条件。

3. 关系的项目
答:关系可以使用四个关键词表达:
    1) Relationship
    2) Role
    3) Multiplicity
    4) Navigability

4.  多样性(Multiplicity)
答:1) 一对一:一个bean的一个实例和另一个bean的一个实例最多有单一的关系, 反过来也是。
    2) 一对多:一个bean的一个实例可以和另一个bean的多个实例相联系,但是另一个bean和第一个bean最多有单一的关系。
    3) 多对多:一个bean的一个实例可能和另一个bean的多个实例相联系,反过来也是。

5.  EJB的继承
答:1) 定义一个实体bean作为别一个实体bean的子类并非EJB规范中的东西,但在真实的应用程序中,我们需要这种需向对象编程的本质特征。
    2) 在WSAD和WAS中直接实现了这种规范。
    3) 应用程序开发者提供不同的映射实现继承层次结构,单表方法,表间用外键相联系的根/叶方法。

6.  继承预览
答:WSAD支持两种类型的继承:
    1) Java继承
    2) EJB继承
       . 实体bean继承处于同一个EJB模块中的另一个实体Bean的相关属性,例如CMP字段和关系角色,方法以及方法层的控制描述符属性。
       . 因为EJB继承几乎只能在相同的EJB模块中,子类和父类均要在同一个模块中。

7.  EJB继承的特征
答:1) 对于CMP实体bean,对单个表和根/叶表映射存在支持;
    2) DD中将会列出所有的CMP字段,包括继承的字段;
    3) 主接口类不能和其它的主接口类继承,因此我们不得不自已提升所有相关的方法;
    4) 远端接口类能继承其它远端接口,这意味着我们能在子bean中直接继承定义在父bean中的商业方法。我们只需提升子bean中特有的商业方法;
    5) 子bean的bean class继承了父bean的bean class;
    6) Key class在继承模式中对于多个企业bean是共享的。这意味着子bean中的key class和父bean中的key class是相等的。
    7) 对于BMP类型的实体bean, 你可以使用映射模式,但是你自己要写JDBC访问代码。

8.  Java继承
答:1) 在Java继承中,一个实体bean class继承了超类的属性和方法;
    2) 远端接口继承了超类实现的商业方法;

9.  Java继承的特征
答:1) bean class继承了超类A,实现了接口B。远端接口能继承定义了商业方法的接口B。
    2) 从同一个超类继承的子类是完全不同的bean,它们有不同的映射以及各自的模式。
    3) 继承的子类有不同的用来表征它们的key class。
    4) 假如超类中有状态,确信状态是持续的。

10. Java继承的好处
答:1) Java继承模式在我们已经有一个实现了bean的逻辑的类时非常有用。
    2) 作为继承的一个优点,它使代码能重用。
    3) 但这种模式对于数据库映射来说没有帮助,因为底层的表并没有反映继承。

11. 单表映射继承模式
答:1) 在继承模式中所有的类映射为单个的表。
    2) 一个辨别的字段指定了子类的实例类型。
    3) 这个辨别的字段不是任何实体bean的属性,它只用于映射。

12. 单表映射的好处
答:1) 在单表映射模式中,这个数据表不是很规范。用于指定一个bean的字段没有必要和其它bean紧密关联。
    2) 但是这种模式容易访问数据表。
    3) 这种模式一个实际的局限性在于当我们通过继承现有的bean模式创建一个新的实体bean时,我们必须改变表的定义:为bean增加其特有的字段。
    4) 因此,单表映射模式适用于父bean的CMP字段多于子bean时。

13. 根/叶表映射继承模式
答:1) 在根/叶表映射模式中,你为在继承层次中的每一个企业bean创建一个表;
    2) 根表包含了父bean中专有的字段以及辨别字段。
    3) 因为一些字段和子bean继承属性相关,这个表也包括子bean属性的状态。

2004-10-27     星期三      晴

使用WSAD开发、调试以及测试EJB、JSP和Servlet(EJB第十一天)

14. EJB用户查询方法
答:1) 查询方法用于查找既存的实体bean,通过和持久层交互在数据库中寻找和实体bean对应的记录。可返回一至多个bean。这些查询方法在实体bean的home接口中。
    2) 单对象查询方法返回一个bean类型,多对象查询方法返回一个collection。

15. EJB QL
答:1) 我们仅关注CMP实体bean模式的查询方法开发。
    2) 假如你使用CMP类型bean,你可以在你的查询中使用新的EJB QL。EJB QL通过使用属性(CMP字段)和关系(CMR字段)对CMP类型的实体bean指定一个查询语句。
    3) 这种语言类似于SQL,它是SQL的一个子集。
    4) EJB QL用于定义实体bean的抽象持久化模式,而不是底层的数据存储。因此它们很容易适用于不同容器。EJB QL定义在部署描述符中,当Bean被部署时,EJB容器基于EJB QL产生实际的SQL代码。

16. finder和select方法的比较
答:1) 标准            | Finder方法                 | Select方法
       -------------------------------------------------------------------------------
       在哪里声明      | 远端或本地的home接口       | bean class中抽象的方法
       -------------------------------------------------------------------------------
       方法名字        | findXxxx(home接口中)       | ejbSelectXxxx(bean class中)
                       | ejbFindXxxx(bean class中)  |
       -------------------------------------------------------------------------------
       可见性          | 客户端可见                 | 位于实体bean内,被其它bean方法使用
       -------------------------------------------------------------------------------
       实例            | bean实例池中任何一个抽象的 | 当前的实例,但如果是home方法调用,
                       | bean实例                   | 可以是任何一个实例
       -------------------------------------------------------------------------------
       返回值          | 主接口:返回单个的对象     | 单个或对象集合。对象类型可以是
                       | (EJBOBject或EJBLocalObject)| EJBOBject或EJBLocalObject、CMP字段
                       | 或一个集合                 |
                       | bean实例:主键             |
       -------------------------------------------------------------------------------
       异常            | FinderException或          | FinderException或
                       | ObjectNotFoundException    | ObjectNotFoundException

17. select方法
答:1) select方法有时称为私有finder方法,这些方法只位于一个bean class内。与新的home接口方法结合,你能实现很复杂的对超过一种实体bean类型的操作。
    2) select方法使bean class内部有私有的查询方法,这样的话,不会通过home接口将这些功能暴露给客户。

消息驱动Bean

1.  介绍
答:1) 消息驱动bean是EJB2.0规范中令人兴奋的特点;
    2) 它们开启了一个崭新的框架领域,提供以前J2EE所不能提供的综合选择。
    3) 消息驱动bean是EJB2.0中的新东西,对于WebSphere5.0同样是新的。

2.  非同步通信
答:1) 非同步通信是一种消息的发送方式,进一步来说,是无需等待回复的一种消息发送方式。
    2) 非同步通信是不同应用程序间或应用程序的不同组件间会话的一种方式。
    3) 我们已看到应用程序客户端可以通过RMI/IIOP和EJB会话。通信的方式有:RMI、COM/DCOM、CORBA、Web services/SOAP、异步通信
    4) 异步通信是一种调用EJB的可选会话机制,消息的产生者(EJB客户)和消息的消费者(消息驱动bean)间会话通过第三方的建造机制,面向对象的中间件(MOM),例如WebSphere MQ。
    5) 这样,MOM截取产生者和消费者间的所有消息,然后处理它们。

3.  JMS和JMS提供者的角色
答:1) JMS(Java Message Service)是Java中访问MOM服务的API。
    2) 所有支持EJB2.0规范的应用服务器必须基于JMS编程接口支持异步通讯这种会话的方式。
    3) JMS对Java程序(客户端和J2EE应用程序)提供一种公共的方式去创建、发送、接收以及读取异步请求作为JMS的消息。
    4) 就像任何一种J2EE API,JMS只是一种公共的、轻便的编程模式的抽象。它并不真正提供运行时的实现或底层消息服务,这由MOM提供。因此,对于支持EJB2.0规范的应用服务器也必须提供一种新型服务:JMS消息服务器。
    5) WAS 5.0 提供内置的JMS消息服务器作为WebSphere产品的基础。内置的JMS服务器在本质上是一种轻量级的WebSphere MQ, 它允许处于同一个服务器中的应用程序间交换消息。
   
4.  MDB介绍
答:1) MDB用于处理J2EE应用程序中异步的JMS消息。
    2) 当消息来了的时候,它们被容器调用。因此它们可以看做是另一种调用EJB的机制。
    3) 但不同于会话和实体bean的是,当消息来了的时候,是容器,而不是客户端,有责任调用它们。
    4) 虽然MDB有时被称为没有一个真实的客户,其实客户就是消息的产生者。
    5) MDB的非常重要的特性:
       . 它们对于客户端不可见,是匿名执行的。
       . 它们完全被EJB容器所管理。
       . 它们是无状态的,不能够维护客户端的任何状态。
       . 它们必须实现javax.jms.MessageListener和javax.ejb.MessageDrivenBean。
       . 它们没有组件和home接口。

5.  java消息服务的相关概念
答:1) JMS是一种访问MOM系统的Java API。
    2) 和JDBC对于数据库访问类似,JMS对于消息是供应商无关的访问方式。
    3) MDB实际上是JMS消息到达后调用的EJB。
    4) 因为JMS是MDB的支柱,所以理解JMS的基础概念很重要。

6.  JMS消息模式之P2P
答:1) 在端对端中,消息通过队列(queues)传输;
    2) 消息被消息的提供者(客户端)放入队列的;
    3) 端对端典型地用于消息只被消费者处理一次的情形;
    4) 这种情形下,消息只有一个消费者。

7.  JMS消息模式之pub/sub
答:1) 在发布-订阅模式中,消息通过主题发布;
    2) 消息由消息产生者发布为主题;
    3) 消息可被任何一个订阅了该主题的消费者接收;
    4) 通过这种方式,一个消息可被多个消费者接收或处理。

8. JMS提供者
答:1) JMS提供者是消息系统的基础,它们是一些实现了JMS API的Java类;
    2) JMS提供者资源通过JMS连接工厂和目的对象可访问。
    3) 提供者要么是WebSphere内置的轻量级的MQ,要么是外置的如WebSphere MQ。

9. JMS服务器
答:1) JMS提供者的JMS功能可通过应用程序服务器中的JMS服务器访问;
    2) JMS服务器有责任管理下列服务:
       . 队列管理:在使用P2P情形时提供队列服务;
       . 代理:在使用pub/sub情形时提供服发布/订阅服务;

10. JMS连接工厂
答:1) 连接工厂用于为一个指定的JMS队列或主题目标创建连接。每个连接工厂封装了创建一个JMS目的地连接的配置参数;
    2) 将连接的细节存储于JNDI使用应用程序的连接代码与供应商无关。存在两种类型的JMS连接工厂:
       . QueueConnectionFactory: 封装了创建一个基于队列的消息系统的设置;
       . TopicConnectionFactory: 封装了创建一个基于主题的消息系统的设置。

11. JMS目的地
答:1) 一个JMS目的地提供一个指定的消息末端;
    2) 有两种类型的JMS目的地:
       . Queues: 用于P2P;
       . Topics: 用于pub/sub;

12. 发送消息到队列的Java代码
答:InitialContext initCtx = new InitialContext();
    QueueConnectionFactory qcf = (QueueConnectionFactory)iniCtx.lookup("java:com/env/jms/ItsoMDBConnectionFactoryRef");
    QueueConnection conn = qcf.createQueueConnection();
    QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    Queue queue = (Queue)initCtx.lookup("java:comp/env/jms/ITSOMdbQueueRef");
    QueueSender sender = session.createSender(queue);
    TextMessage msg = new TextMessage("Test Message");
    sender.send(msg);
    sender.close();
    session.close();
    conn.close();
    说明:. QueueConnection: 用于创建到JMS消息服务器的一个活动的连接,用于创建QueueSessions.类似于JDBC中的connection对象。在pub/sub模式中,会使用TopicConnection;
          . QueueSession: 使用创建sender对象和消息。一次只能被一个线程所使用。在pub/sub模式中,会使用TopicSession。
          . QueueSender: 用于发送消息到队列,在pub/sub模式中,会使用TopicPublisher。
          . TextMessage: 一个简单的文本消息类型。另外一些类型是ObjectMessage, BytesMessage, StreamMessage以及MapMessage。每个message类型继承了Message超类。
          在这个列子中, 一个简单的文本消息发送到队列中,一个很好的习惯是完成任务后及时关闭这些对象,就如你对JDBC类型对象做的那样。

13. JMS消息侦听器
答:import javax.jms.*;
    public class AListener implements MessageListener {
      public void onMessage(Message aMsg) {
        try {
          TextMessage msg = (TextMessage)aMsg;
          System.out.println("Got Message: " + msg.getText());
        } catch(Exception e) {
          e.printStackTrace();
        }
      }
      public void runIt() {
        ...
        QueueReceiver rec = session.createReceiver(queue);
        rec.setMessageListener(this);
        rec.close();
        ...
      }
    ...
    }
    说明:. 所有的标准消息侦听器必须实现javax.jms.MessageListener接口,因此这个对象能被注册成为一个JMS Listener;
          . 在这个例子中,我们将自己注册为一个侦听器。对于一个MDB,容器会注册这个bean为一个listener。
          . 当一个JMS消息到达时,容器触发onMessage方法。

14. 消息驱动bean的结构
答:再次重申消息驱动bean实现了javax.ejb.MessageDrivenBean接口,也实现了javax.jms.MessageListener接口。

    javax.ejb.EnterpriseBean               javax.jms.MessageListener
                ↑                                      ↑
                |                                       |
     javax.ejb.MessageDrivenBean                        |
                ↑______________________________________|
                                    |
                                  MyMDB               
15. 没有home或component接口
答:1) MDB不需要home或component接口,因为没有客户端直接和它打交道;
    2) home接口用于定位bean,唯一处理这个实例的是容器,容器有足够的能力定位MDB;
    3) component接口的目的是为客户端提供商业逻辑的访问入口。虽然MDB在onMessage方法调用时会实现商业逻辑,但bean本身并不需将这些提供给外在的客户端。

16. MDB的状态
答:有二种状态的MDB,要么不存在,要么处于method-ready pool状态。消息驱动bean的method-readey pool有点像无状态会话bean的instance pool。
                                      
                setMessageDriverContext()
       No State--------------------------->Method Ready Pool
               <---------------------------
                       ejbRemove()

17. 构建消息驱动bean
答:1) 当我们构建消息驱动bean时,我们指构建bean class和部署描述符
       . Bean class:必须包括回调方法以及实现onMessage方法;
       . 部署描述符:这个bean的XML格式的描述符;
       商业逻辑是什么?让消息驱动bean承担商业逻辑并不推荐,一个好的方法是将它委派给无状态会话bean。按照这种思路,无状态会话bean完成商业逻辑的具体实现,消息驱动bean只是简单地扮演商业逻辑委派者角色。

18. 一个回复是怎样的?
答:1) 非同步消息通常是一个触发-遗忘行为,对于消费者而言,并不期待或需要回复;
    2) message-consumer MDB能处理消息,然后作为JMS消息的产生者发送回回复;
    3) 这个原先的消息产生者必须侦听由消费者发送回的消息请求,这时候它也是一个JMS消息消费者。
    4) 这有点像一个队列用于发送,另一个队列用于响应。

EJB的客户端

1.  客户端类型
答:1) sessin bean: 一个会话bean可以看作是它所访问的实体bean的客户端。在大多数时候,会话bean和实体bean运行于同一上EJB容器中,因此能够使用本地接口;
    2) servlet: servlet可通过远端或本地接口和EJB交互。一个推荐的访问方式是:servlet只和会话bean打交道,会话bean再和实体bean打交道。servlet可使用远端或本地接口访问会话bean,推荐使用远端接口。servlet是典型的瘦客户端实现,用户端是HTML和JSP,他们调用serv的 J2EE application client: 这是一些访问企业bean,JDBC数据库以及Java消息服务队列的Java应用程序。它们运行在客户端机器,使用JNDI命域空间访问资源。RMI-IIOP协议使应用程序客户端访问企业bean引用以及使用J2EE平台实现的CORBA服务。

2. MVC设计模式
答:1) MODEL: 封装了所有的商业逻辑以及规则。通常被JavaBean或EJB实现。
    2) VIEW: 使用商业逻辑处理后的结果并构建呈现给客户端的响应。通常被JSP实现。
    3) CONTROLLER:管理和控制所有用户和应用程序间的交互。通常是一个servlet接收用户的请求并把所有的输入转交给实际工作的MODEL。最后调用JSP返回输出。

3. MVC的好处
答:1) 它将逻辑层从表现层以及控制层中清晰地分隔出来;
    2) 它允许使用三层结构,逻辑层和表现层分置于不同的服务器上,可应用不同的安全模式;
    3) 它使一个开发团队角色分工成为可能,页面设计与商业逻辑开发无缝地结合;
    4) 当应用这种编程模式于Web应用程序,用于将数据或对象从servlet运送至JSP的媒介物是HttpServletRequest或HttpSession;
    5) 当一个用户向服务器请求资源时,请求对象包含有一个web浏览器发送到一个web服务器的所有信息。

4.  如何访问EJB?
答:从任何类型客户端访问EJB的步骤是:
    1) 获得home接口;
    2) 寻找或创建EJB对象;
    3) 调用EJB实例的商业方法。

5.  基本的编程原则
答:1) 首先, 我们将看到我们能写一个简单的可找到并使用位于EJB容器中EJB的客户端;
    2) 在访问EJB服务器中的企业bean之前,一个客户端必须依随一定的步骤。这些步骤是:
       . 获取一个初始的命名上下文:当我们写一个EJB客户端,你有责任去创建一个JNDI的InitialContext。通过它能钩住应用程序服务器的命名服务。获得初始化上下文的最简单形式为使用它的构造器:
         javax.naming.InitialContext initialContext = new javax.naming.InitialContext();
       . 从初始化上下文中寻找EJB的主接口:使用初始化上下文,我们可以得到我们想要访问的实体bean的主接口。对一个远端主接口我们可以能使用全局JNDI名称或一个EJB引用。对一个本地主接口,我们必须使用一个本地引用。
       . 使用EJB主接口:拿到EJB主接口后,我们可创建、查找和移除实体bean。注意大多数方法会抛出FinderException和RemoteException异常。这些异常必须使用try/catch处理。
       . 使用EJB引用:在获得组件接口后,我们可以调用商业方法,当然也可以调用EJB Object中的Remove方法。

6.  客户端访问实体bean的类型
答:

                    client                                       Server
       |ˉˉˉˉˉˉˉˉˉˉˉˉˉˉ|              |ˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉˉ|
       | |ˉˉˉˉˉ|---------------|-|ˉˉˉˉˉ|-|--------------->|ˉˉˉˉˉˉ|  |
       | | Servlet  |---------------|-| Network  |-|--------------->| Entity Bean|  |
       | |__________|---------------|-|__________|-|--------------->|____________|  |
       |                            |   RMI-IIOP   |                                |
       |                            |              |                                |
       |                            |              |                                |
       | |ˉˉˉˉˉ|->|ˉˉˉˉˉ| | |ˉˉˉˉˉ| |                |ˉˉˉˉˉˉ|  |
       | | Servlet  |->|AccessBean|-|-| Network  |-|--------------->| Entity Bean|  |
       | |__________|->|__________| | |__________| |                |____________|  |
       |                            |   RMI-IIOP   |                                |
       |                            |              |                                |
       |                            |              |                                |
       | |ˉˉˉˉˉ|               | |ˉˉˉˉˉ| | |ˉˉˉˉˉˉ|->|ˉˉˉˉˉˉ| |
       | | Servlet  |---------------|-| Network  |-|-|Session Bean|->| Entity Bean| |
       | |__________|               | |__________| | |____________|->|____________| |
       |                            |   RMI-IIOP   |                                |
       |____________________________|              |________________________________|

    Client type   |    Yes, when                 |    No, when
    ---------------------------------------------------------------------------------
    Direct access | . 模型简单                   | 实体bean存在多个属性
                  | . 效率不重要                 |
    ---------------------------------------------------------------------------------
    Access beans  | . 需要简单快速的开发         | . 需要更复杂的设计模式
                  | . 服务器的系统资源有限       | . 多个应用程序的集群环境
                  | . 用Java的包装器访问会话bean |
    ---------------------------------------------------------------------------------
    Facade beans  | . 可量测试性很重要           | . 客户端需要访问会话bean 
                  | . 应用开放设计               | . 开发时间很重要
                  | . 整体性能高                 |

部署应用程序

1.  创建应用程序服务器
答:1) 当WebSphere应用程序服务器安装后,已自动创建了一个服务器(server1);
    2) 虽然你的程序可部署到黙认的服务器,我们还是建议您为您自己的程序创建一个独立的服务器;
    3) 默认的服务器主要是运行WebSphere范例以及一些模板;

2.  改变服务器的端口号
答:当我们创建应用程序服务器,我们让这个系统为Web容器定义了一个默认的HTTP端口号。我们可以自行改变它。

3.  创建JDBC提供者和数据源
答:访问数据库,我们需定义数据源,然后我们可以将此数据库和我们的实体bean相联系。

4.  配置WebSphere的JMS提供者
答:我们需要使用内置的WebSpherer JMS provider, MQSeries. 在WebSphere中进行相关配置。

5.  部署应用程序
答:现在我们已经创建了这个应用程序所需的所有资源,可以准备部署了。

你可能感兴趣的:(Java)