首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | linux相关 | linux认证 | 下载中心 | 专题
oklinux
 系统管理:中文环境 系统管理 桌面应用 内核技术 Linux基础:安装配置 常用命令 经验技巧 软件应用 Linux数据库:Mysql POSTGRE
 网络管理:网络安全 网络应用 Linux服务器 编程开发:PHP CC++ Python Perl SHELL 嵌入式开发 | PHP基础 PHP技巧 PHP应用 PHP文摘
 首页 linux资讯动态 Linux专题 | 其他Unix Linux解决方案 硬件相关 Linux认证 企业应用 Apache | 相关下载:资料 参考手册 服务器
 → 当前位置:首页>编程开发>java>Java基础>正文

EJB 最佳实践--工业强度的 JNDI 优化

OKLinux www.oklinux.cn 2008-01-28 来源:赛迪网 billhepeng 会员收藏 游客收藏

Brett McLaughlin 在这篇 EJB 最佳实践专栏文章中研究了 JNDI 查找,它是几乎所有的 EJB 交互中不可或缺并且常见的部分。遗憾的是,JNDI 操作几乎总是需要性能开销。在本技巧文章中,Brett 向您展示了 home 接口工厂是如何降低您 EJB 应用程序中 JNDI 查找开销的。
每种 EJB 组件(会话、实体和消息驱动的)都有 home 接口。home 接口是 bean 的操作基础;一旦您找到它,就可以使用该 bean 的功能。EJB 应用程序依靠 JNDI 查找来访问其 bean 的 home 接口。因为 EJB 应用程序往往运行多个 bean,并且因为许多组件中经常使用 JNDI 查找,所以应用程序大部分性能开销都花费在这些查找上。

在这篇技巧文章中,我们将研究一些最常用的 JNDI 优化。特别地,我们将向您展示如何将高速缓存和通用助手类组合使用,以创建针对 JNDI 开销的工厂风格的解决方案。

减少上下文实例

清单 1 显示了一段典型的 EJB 代码,它需要多次 JNDI 查找。请花一点时间研究代码,然后我们将对它进行优化以获得更佳性能。


清单 1. 典型的 EJB 查找

public boolean buyItems(PaymentInfo paymentInfo, String storeName,
List items) {
// Load up the initial context
Context ctx = new InitialContext();

// Look up a bean's home interface
Object obj = ctx.lookup("java:comp/env/ejb/PurchaseHome");
PurchaseHome purchaseHome =
(PurchaseHome)PortableRemoteObject.narrow(obj, PurchaseHome.class);
Purchase purchase = purchaseHome.create(paymentInfo);

// Work on the bean
for (Iterator i = items.iterator(); i.hasNext(); ) {
purchase.addItem((Item)i.next());
}

// Look up another bean
Object obj = ctx.lookup("java:comp/env/ejb/InventoryHome");
InventoryHome inventoryHome =
(InventoryHome)PortableRemoteObject.narrow(obj, InventoryHome.class);
Inventory inventory = inventoryHome.findByStoreName(storeName);

// Work on the bean
for (Iterator i = items.iterator(); i.hasNext(); )
inventory.markAsSold((Item)i.next());
}

// Do some other stuff
}



尽管这个示例多少有点刻意,但它确实揭示了使用 JNDI 时的一些最明显的问题。对于初学者,您应该问问自己,新建 InitialContext 对象是否必需。很可能在应用程序代码的其它地方已经装入了这个上下文,而我们又在这里创建了一个新的。高速缓存 InitialContext 实例会立即促使性能提高,如清单 2 所示:


清单 2. 高速缓存 InitialContext 实例

public static Context getInitialContext() {
if (initialContext == null) {
initialContext = new InitialContext();
}

return initialContext;
}



通过对 getInitialContext() 使用助手类,而不是为每个操作都实例化一个新的 InitialContext ,我们将遍布在应用程序中的上下文数量减少为一个。

哦 ― 线程化会怎么样?

如果您对此处提出的解决方案的线程化感到担心,那大可不必。两个线程同时进行 getInitialContext() 是绝对有可能的(从而一次创建两个上下文),但只有首次调用该方法时才会发生此类错误。因为问题至多只会发生一次,所以同步是不必要的,实际上,同步引入的复杂性比它所解决的复杂性更多。

优化查找

高速缓存上下文实例这个步骤的方向是正确的,但仅这样做,还不足以完成优化。我们每次调用 lookup() 方法时都会执行一次新查找,并返回 bean 的 home 接口的新实例。至少,JNDI 查找通常是这样编码的。但如果每个 bean 都只有一个 home 接口,并在多个组件上共享这个接口,这样不是更好吗?

我们可以高速缓存每个单独的 bean 引用,而不是反复查找 PurchaseHome 或 InventoryHome 的 home 接口;这是一种解决方案。但我们真正想要的是一种更通用的机制:在 EJB 应用程序中高速缓存 home 接口。

答案是创建通用助手类,它既可以为应用程序中的每个 bean 获取初始上下文,又可以为它们查找 home 接口。此外,这个类还应该能够为各种应用程序组件管理每个 bean 的上下文。清单 3 中所示的通用助手类将充当 EJB home 接口的工厂:


清单 3. EJB home 接口工厂

package com.ibm.ejb;

import java.util.Map;
import javax.ejb.EJBHome;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBHomeFactory {

private static EJBHomeFactory;

private Map homeInterfaces;
private Context context;

// This is private, and can't be instantiated directly
private EJBHomeFactory() throws NamingException {
homeInterfaces = new HashMap();

// Get the context for caching purposes
context = new InitialContext();

/**
* In non-J2EE applications, you might need to load up
* a properties file and get this context manually. I've
* kept this simple for demonstration purposes.
*/
}

public static EJBHomeFactory getInstance() throws NamingException {
// Not completely thread-safe, but good enough
// (see note in article)
if (instance == null) {
instance = new EJBHomeFactory();
}
return instance;
}

public EJBHome lookup(String jndiName, Class homeInterfaceClass)
throws NamingException {

共2页: 上一页 1 [2] 下一页
上一篇:J2SE综合--浅谈 String 类的相关应用   下一篇:Ubuntu Linux系统中安装VirtualBox方法

收藏于收藏夹】 【评论】 【推荐】 【投稿】 【打印】 【关闭

相关文章
·J2SE综合--浅谈 String 类的相关应用
·JSP/Servlet:EasyJWeb中文件上传的处理
·J2EE综合--选择应用服务器的七个标准
·J2SE综合--怎样取得class文件的路径
·Java语言深入--java调用C/C 的过程
·Java 理论和实践:用软引用阻止内存泄漏
·初始化引发的"StackOverflowError" 异常
·接口与抽象类的深层理解
·Java入门:java语言中创建和使用日期
·Java怎样调用外部应用程序
发表评论
密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。)
站内搜索
阅读排行榜
·使用AJAX技术实现网页无闪
·快速教您Apache Tomcat
·详细讲解Struts构架中acti
·对于JSP中表单数据存储的
·Hibernate配置文件中的映
·在JSP环境中配置使用fcked
·用JSP JavaScript打造二级
·高级:运用Jakarta Struts
·JSP获取客户端的浏览器和
·数据库相关:小结Hibernat
最新文章
·J2SE综合--浅谈 String 类
·JSP/Servlet:EasyJWeb中
·J2EE综合--选择应用服务器
·J2SE综合--怎样取得class
·Java语言深入--java调用
·Java 理论和实践:用软引用
·初始化引发的"StackOverfl
·接口与抽象类的深层理解
·Java入门:java语言中创建
·Java怎样调用外部应用程序
·J2EE综合--浅谈Java程序员
·关于角色访问控制(RBAC)
·J2SE综合--为什么Java中继
·进阶-Java Web中的入侵检
·基础--websphere下JMS的

设为首页 - 加入收藏 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
Copyright © 2007 All rights reserved OKLinux.Cn 版权所有