Enterprise JavaBeans 入门
客户端开发和测试
本章主要讲述以下内容:一个客户端应用的构成;JNDI 的工作方式以及使用 home 接口和会话 bean 等相关的知识。
本章讲述内容
- 一个客户端应用的构成?
- JNDI 是如何工作的
- 使用 home 接口
- 使用会话 bean
EJB 客户端
- 看起来很特殊的 EJB 客户端应用实质上一点也不特殊
- 可以是 applet, 应用程序, servlet, 或其它 bean
- 没有过高的 overhead
- 编程模式简单
JNDI
- 使用 JNDI (Java Naming and Directory Interface) 来查找一个 EJB home 接口
- JNDI 是将名称与对象匹配的服务(类似电话黄页)
- 一个 "naming service"
- 一个服务器将对象添加到目录树上:Known as "binding" a name to an object
- 任何一种对象可以被加到目录树中
JNDI Context
- 一个 Context 是一个将名称与对象绑定好的对象
- Context 可以是嵌套的 (构成一个目录结构):顶级的 context 对象是一个 InitialContext
- Context 可以被 "列出" 来查看其中的内容
Binding
- Context 接口定义了下列方法
- void bind(String name, Object obj)
- Object lookup(String name)
- 一个容器当 Bean 启动后自动将 Bean 的名称绑定到它的 home 对象上
- 一个客户端通过名称就可查找到 home 接口
为何使用 JNDI?
- 服务器和客户端需要知道:
- 客户端不知道如何定位 EJB 服务器:客户端必需知道如何找到名称服务器
- 通过名称服务器存取的对象可以来自多方面:多个服务器可以构成命名空间
获得您的 Bean
- 一旦您获得一个 home 接口,您可以使用 create() 方法来获得一个 bean 的引用:一旦您获得对该 bean 的引用,您可以开始调用它的方法
- 不需要任何扫尾工作;只需简单地"停止引用" bean
|
try { MyBean bean = findMyBeanHome().create(); bean.computeSomethingOrOther(42); ... } catch (NamingException e) { // Handle the naming exception } |
|
找到回 Home 的路
- 每个 EJB 都有一个 home 接口
- 客户端可从一个 JNDI context 获得 home 接口
- 使用一个 helper 类将它 "narrow" 成正确类型
|
public MyBeanHome findMyBeanHome() throws NamingException { Context context = getInitialContext(); Object object = context.lookup("MyBean"); context.close(); return (MyBeanHome)PortableRemoteObject .narrow(object, MyBeanHome.class); } |
|
创建一个 InitialContext
- INITIAL_CONTEXT_FACTORY
- PROVIDER_URL
- 名称服务器的位置 (URL 格式)
- "IIOP://localhost:6543/" == 本地机器,端口 6543
|
public Context getInitialContext() throws NamingException { Hashtable properties = new Hashtable(2); properties.put(Context.PROVIDER_URL, "iiop://localhost:6543/"); properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.ejs.ns.jndi.CNInitialContextFactory"); return new InitialContext(properties); } |
|
注意这些 "魔术" 值
- 这些 "常量" 不应该写死在您的方法中
- 应该从一个 properties 文件中获得,或为 servlet "init" 参数,...
|
public Context getInitialContext() throws NamingException { Hashtable properties = new Hashtable(2); properties.put(Context.PROVIDER_URL, getNameServerURL()); properties.put(Context.INITIAL_CONTEXT_FACTORY, getInitialContextFactoryClassName()); return new InitialContext(properties); } |
|
要及时关闭Context
- Context 不是线程安全的 (thread-safe):当您要共享它们时要当心
- 一旦您获得了对象的引用,您不再需要 context; 可以关闭它
|
... Context context = getInitialContext(); Information info = null; try { info = (Information)context.lookup("information"); } catch (NamingException e) { throw e; } finally { context.close(); } ... |
|
引用 Bean
- 您可以不确定地引用一个 home 或 bean 类
- 实际上,我们建议您保存 home 接口如果您还将使用它们时:JNDI 的查找是开销很大的
- 但要注意,home/bean 的引用不是 serializable 的
|
... MyBean bean = findMyBeanHome().create(); bean.computeSomethingOrOther(42); ... |
|
Servlet 示例
public void doGet(...) throws ... { PrintWriter out = response.getWriter(); out.println(""); try { BankAccount account = getBankAccountHome().findById(42); double balance = account.getBalance(); out.print("Balance is: "); out.println(balance); } catch (Exception e) { out.println("A problem has occurred with the server."); } out.println(""); } |
|
public synchronized BankAccountHome getBankAccountHome() throws NamingException{ if (bankAccountHome == null) bankAccountHome = findBankAccountHome(); return bankAccountHome; } |
|
EJB 客户端开发流程总结
本章讲述内容
- 构建一个 EJB 客户端的流程
- JNDI 提供了一个分布式对象有层次的组织
- 客户端和服务器不需要互为知道
- 客户端和服务器必需知道:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130487/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-130487/