这个年代还在写EJB 2.1的东西感觉很怪,毕竟我在网上寻找答案的时候发现绝大多数提问的帖子都是04年以前的了,如今也没什么人还会用EJB 2.1以下的版本做项目。然而,实际生产总是跟不上潮流的,公司里需要我维护的还是EJB 1.x 与 2.x 的系统呢,不学也是没办法。
写这篇文章,一来是为了帮自己记着点,二来是看到相关问题在网上总是找不到满意的答案,被提问的高手(或假高手)大都语焉不详,解释了半天也没提供一点可操作性,甚是失望。查书的结果也让人沮丧。死样活气的 “NameNotFoundException” 简直把人气到无语。如今把搜索了好几天、研究了好几天的成果写下来,只怕不会因为它基础、简单而毫无价值。废话少说,开始吧。
1. 要使用本地接口访问 EJB,首先自然是在 ejb-jar.xml 里面规定 <local> 和 <local-home> 接口的类(当然前提是你已经写好了这两个接口,不要笑,不少初学都会摆这个乌龙)。这里需要注意的是, EJB 2.x 的规范是不允许同时配置本地和远程接口的,你只能选择其中一个,这一点只要在一个有 xml 检查机制的编辑器(如 MyEclipse 自带的编辑器,或者大名鼎鼎的 XMLSpy )里就可以看出来。
2. 其次,在客户端(我一般是用 servlet,jsp 也可以。注意不能用独立客户端,它只能用远程方式访问 EJB )写调用代码。写法99%和远程访问差不多,需要改的地方只有三个:
a) 所有的接口引用都改成对应的本地接口,如 ProductHome --> ProductLocalHome, Product --> ProductLocal 等。
b) PortableRemoteObject.narrow() 方法不需要了,直接强制转型即可。参考这里的讨论: http://topic.csdn.net/t/20040419/09/2981624.html
c) 在做 context.lookup() 的时候,查找字串必须是 "java:comp/env/xxx" 的格式,这里要注意 xxx 不再是所调 EJB 的 jndi 名了,你可以自由指定,原因后面再说。
3. 配置 ejb-jar.xml 或 web.xml 文件。这一步最关键,因为大多数人都是在这里崩溃的,遇到 NameNotFoundException 一点都不美。这里到底是配置 ejb-jar.xml 还是 web.xml 呢,这就看你的“客户端”是什么了。如果你使用 session bean 来访问 entity bean (其实只要是两个EJB就适用,类型不限),那么就配置 ejb-jar.xml ; 如果用 servlet 或 jsp 来访问 EJB 就改 web.xml 。
如果是 ejb-jar.xml, 则在<enterprise-beans><ejb>...</ejb></enterprise-beans> 中加入以下描述符;
如果是 web.xml, 则在根标签<web-app>...</web-app> 中加入以下描述符;
<ejb-local-ref>
<ejb-ref-name>ejb/ProductLocal</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>examples.cmp.ejb.ProductLocalHome</local-home>
<local>examples.cmp.ejb.ProductLocal</local>
<ejb-link>ProductEJB</ejb-link>
</ejb-local-ref>
这一段的作用是把一个本地 EJB 组件作为资源注入客户端的运行环境。标签里的具体内容仅作示例。 说明一下:
1) <ejb-ref-name> 是客户端 lookup EJB 时的名字,也就是上面提到的 "java:comp/env/xxx" 里面的 xxx, 惯例是推荐前面都带一个ejb/ 的了,倒是无所谓。
2) <ejb-link> 是该 EJB 资源的名字即它在自己的 ejb-jar.xml 里的<ejb-name>。
到这里可能有人糊涂了,Jndi 在哪里呢?这正是本文的重点所在。事实上,通过本地接口来访问一个 EJB,客户端是不需要知道它的 Jndi 名字的,因为此时采用的是 link 的方式,通过 <ejb-link> 指定的相对路径来访问这个本地资源。与该 <ejb-link> 相对应的 <ejb-ref-name> 实质上就是客户端专有资源的一个 伪Jndi 名。真正的 Jndi 名只在远程调用的时候才有意义,那时候调用被调用双方的相对路径是未知的。
这里真伪 Jndi 有点像
成员变量
和局部变量的关系。
那末,为什么我们在 lookup 的时候不能直接用 <ejb-ref-name> 里面的名字,而是还要加上 "java:comp/env/" 的前缀呢?粗糙点解释就是,这个前缀就是专门用来查找“伪Jndi”的。详细的讲解见 : http://www.blogjava.net/javababy/archive/2006/12/06/85881.html
补充一点,由于 <ejb-link> 是本地相对路径的标识, 首先就限制了调用客户端和 EJB 必须位于同一个 application 即 ear 里。其次,如果 EJB 模块的 jar 包下面还有 包含 EJB 模块的 jar 包,在访问最里面的那个 EJB 的时候就需要把 jar 的路径也写进 <ejb-link> 里去,如 <ejb-link>SalesEJB.jar#ProductEJB.jar#ProductEJB</ejb-link>
。
到这里,文章就算写完了。我是非常奇怪,这么一个基础而常见的问题,要找个现成的答案居然这么难。哎,很多人成了高手,就都忘了初学者的痛苦了,要知道,初学 EJB 2.x 可是 J2EE 世界里最恶心的事情之一,与智力无关,只是太麻烦了。
分享到:
相关推荐
- 不得使用AWT,以确保UI组件不会与EJB组件混合。 - 不得实现服务器功能,保持组件的纯粹性。 - 避免静态属性的使用,防止跨实例数据污染。 - 不允许直接进行文件IO操作,以提高组件的可移植性。 - 不得加载本地库,...
javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....
javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....
EJB (Enterprise JavaBeans) 是 Java 平台为企业级应用提供的一种组件模型。EJB3 是 EJB 的最新版本,相较于之前的版本,它进行了大幅度的简化和改进,引入了许多新的特性来提高开发效率并降低复杂度。 **EJB3 规范...
javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....
**知识点:** 在 EJB 应用程序内部,可以通过直接调用本地接口(Local Interface)的方式来访问同一容器内的其他 EJB 组件。这种方式不需要进行远程调用,因此效率更高。 **应用场景:** 当一个 EJB 需要调用同一容器...
Remote 和 Local 接口定义了客户端与 EJB 交互的方式,Home 接口负责实例化 Bean,而 Bean 类则是业务逻辑的载体。 2. EJB 的三种类型及其作用和实现技术: - 会话 Bean(Session Beans):分为有状态和无状态两种...
- **Remote(或/和Local)接口**:定义远程访问或本地访问接口。 - **Home(或/和LocalHome)接口**:定义如何创建和查找bean实例的方法。 ### 11. J2EE 平台的事务控制服务 - 事务控制可以保证事务所包含的一系列...
业务组件通过EJB容器内部的EJB组件实现。此层主要由会话Bean、容器管理的实体Bean等组成。 ##### 业务逻辑层详细设计 - **会话Bean**:会话Bean是业务逻辑层中的关键组件之一,用于处理具体的业务逻辑。会话Bean...
- 编写EJB涉及Enterprise bean类、Remote(或Local)接口以及Home(或LocalHome)接口。 11. **J2EE平台的事务控制服务**: - 事务控制确保了操作的原子性和一致性,增强了应用的安全性。 以上知识点涵盖了软件...
- EJB包含Remote(Local)接口、Home(LocalHome)接口和Bean类,Enterprise Bean Provider是提供EJB的服务器组件。 **名词解释**: - **JNDI**:Java Naming and Directory Interface,用于查找和访问分布式环境...
- **EJB LocalHome**:LocalHome在EJB中用于创建和查找企业bean实例,提供业务方法的入口。 4. **程序测试题**: - **MyString类**:尝试扩展不可扩展的String类,`i++`在静态初始化块中,每次类加载时执行一次。...
但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理, EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 24、...
- **EJB的角色和对象**:角色涉及开发者、应用组装者、部署者、系统管理员等,主要对象包括Remote(Local)接口、Home(LocalHome)接口和Bean类。 - **EJB的类型**:分为会话Bean(Session Bean)、实体Bean...
* EJB 的角色和三个对象:Remote(Local)接口、Home(LocalHome)接口、Bean 类 * EJB 的几种类型:会话(Session)Bean、实体(Entity)Bean、消息驱动的(Message Driven)Bean * bean 实例的生命周期 * 激活机制...
10. **EJB中的LocalHome接口**用于创建实体Bean的本地实例,提供了一种在容器内部查找和操作Bean的方法。 **程序测试题**涉及类的继承、构造器、变量作用域、静态变量、方法覆盖等概念,具体答案需要根据题目给出的...
2. EJB角色与对象:Bean开发者、应用组装者、部署者等角色,Remote(Local)接口、Home(LocalHome)接口和Bean类是核心对象。 3. EJB类型:会话Bean(状态ful/less)、实体Bean(Bean/Container管理的持续性)和...