最近因为工作需要开始学习Ejb3,遇到了一个让我很郁闷的事情,做一下小小的总结——小心new InitialContext()。

在做客户端的时候,发现连接服务器,搜索数据库,然后返回结果集。每一次执行的时候,第一次总要花更多的时间,之后每一次操作时间就要快很多了。期间找了很多方法,都行不通。一开始以为是Ejb服务器建立服务消耗时间,后来觉得不对,因为Jboss启动的时候,已经将服务启动了。经过一周的排查,终于发现原来是因为new InitialContext()消耗了大量的时间,之后的lookup()方法也会消耗一定的时间。其中,在网络状态良好的情况下,每一次new InitialContext()方法花费大概100毫秒到200毫秒之间,而每一次lookup()大概要花10毫秒到30毫秒之间。因此,决定对代码进行优化,创建了EJBHomeFactory工具类,使用到了单例模式,欢迎大家指教。以下为该类代码:

Java代码
import javax.naming.InitialContext;  
import javax.naming.NamingException;  
 
import com.cithinc.util.Tool;  
 
public class EJBHomeFactory {  
    private static EJBHomeFactory instance;  
    private InitialContext context;  
 
    private EJBHomeFactory() throws NamingException {  
        context = Tool.getInitialContext();  
    }  
 
    public static EJBHomeFactory getInstance() throws NamingException {  
        if (instance == null) {  
            instance = new EJBHomeFactory();  
        }  
        return instance;  
    }  
 
    public Object lookup(String jndiName) throws NamingException {  
        Object obj = new Object();  
        obj = context.lookup(jndiName);  
        return obj;  
    }  
}

其中,Tool.java的文件内容如下:

Java代码
import java.util.Hashtable;  
 
import javax.naming.Context;  
import javax.naming.InitialContext;  
import javax.naming.NamingException;  
 
public class Tool {  
    @SuppressWarnings("unchecked")  
    public static InitialContext getInitialContext() throws NamingException {  
        Hashtable environment = new Hashtable();  
        environment.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");  
        environment.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");  
        environment.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");  
        return new InitialContext(environment);  
    }  
}

然后这样调用:

Java代码
EJBHomeFactory f = EJBHomeFactory.getInstance();  
Object o = f.lookup(remote);

EJBHomeFactory f = EJBHomeFactory.getInstance();
Object o = f.lookup(remote);

这样就可以保证只初始化一次上下文实例,节省大量的时间。

这种用工厂模式解决的办法其实还是有一个问题,就是ejb容器重启后,客户端应该也要重新去new InitialContext,否则用原来的InitialContext去lookup,会抛出错。

想想后,我是这样去解决的。

为每个ejbhome,新建一个ejbHelper类

如:

Java代码  
  1. package com.company.vas.ejb.helper;
  2. import java.rmi.RemoteException;
  3. import javax.ejb.CreateException;
  4. import javax.naming.NamingException;
  5. import com.company.util.Log;
  6. import com.company.vas.ejb.Invoice;
  7. import com.company.vas.ejb.home.InvoiceHome;
  8. public class InvoiceHelper {
  9. private static final String CLASS_NAME = "InvoiceHelpler";
  10. private static InvoiceHome home;
  11. public static Invoice getInvoice() {
  12. try {
  13. if (home == null) {
  14. home = (InvoiceHome) EjbGetter.getEJBHome(
  15. IInvoice.JNDI_NAME, InvoiceHome.class);
  16. }
  17. return home.create();
  18. } catch (NamingException e) {
  19. Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
  20. home = null;
  21. } catch (RemoteException e) {
  22. Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
  23. home = null;
  24. } catch (CreateException e) {
  25. Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
  26. home = null;
  27. }
  28. return null;
  29. }
  30. }
  31. package com.company.vas.ejb.helper;
  32. import java.util.Properties;
  33. import javax.ejb.EJBHome;
  34. import javax.naming.Context;
  35. import javax.naming.InitialContext;
  36. import javax.naming.NamingException;
  37. public class EjbGetter {
  38. public static EJBHome getEJBHome(String service_jndiname, Class homeInterface) throws NamingException{
  39. Properties env = new Properties();
  40. env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
  41. env.put(Context.PROVIDER_URL, "192.168.60.120:1099");
  42. env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
  43. Context ic = new InitialContext(env);
  44. EJBHome ejbHome = (EJBHome)javax.rmi.PortableRemoteObject.narrow(ic.lookup(service_jndiname), homeInterface);
  45. return ejbHome;
  46. }
  47. }

每一次new InitialContext()方法花费大概100毫秒到200毫秒之间,而每一次lookup()大概要花10毫秒到30毫秒之间相关推荐

  1. Java黑皮书课后题第6章:*6.38(生成随机字符)使用程序清单6-10 RandomCharacter中的方法,打印100个大写字母及100个一位数字,每行打印10个

    6.38(生成随机字符)使用程序清单6-10 RandomCharacter中的方法,打印100个大写字母及100个一位数字,每行打印10个 题目 题目描述 程序清单6-10 破题 代码 运行实例 题 ...

  2. Java黑皮书课后题第6章:6.12(显示字符)使用下面的方法头,编写一个打印字符的方法。编写一个测试程序、打印从‘1‘到‘Z‘的字符,每行打印10个,字符之间使用一个空格字符隔开

    6.12(显示字符)使用下面的方法头,编写一个打印字符的方法.编写一个测试程序.打印从'1'到'Z'的字符,每行打印10个,字符之间使用一个空格字符隔开 题目 题目描述 破题 补充:从生成随机字符窥探 ...

  3. 算法017:三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。

    题目:三步问题.有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶.2阶或3阶.实现一种方法,计算小孩有多少种上楼梯的方式.结果可能很大,你需要对结果模1000000007.示例1:输入:n = ...

  4. php100以内质数求和,100以内的质数_PHP质数计算三种方法 php求100以内的质数

    摘要 腾兴网为您分享:PHP质数计算三种方法 php求100以内的质数,自动刷宝,长沙银行,猿辅导,愈加等软件知识,以及cf一键刷枪,业主名录采集软件,卡乐光电,魔方虚拟光驱,掌上徐州,卡农社区,fa ...

  5. Javascript ES6中数组去重最简便的两种方法(大概)

    1.Set 先利用Set创建类数组数据结构实例set,利用set会自动去重的特性,最后用扩展运算符将set赋值给新数组var arr = ['a', 'b', 'c', 'a']var set = n ...

  6. 染色(方法:要统计每个数出现的次数,而这个数很大,用数组存不了,怎么弄?)

    https://www.nowcoder.com/acm/contest/133/A 题意:就是给出一棵树,每个节点都有价值,问把所有节点都改成一种价值的最小花费,改一条边的两个节点所需的花费是两个节 ...

  7. 红旗桌面4.0正式版最新使用方法和问题解答100例

    原作:dsj兄 来源URL: http://www.linuxsir.com/bbs/showthr...?threadid=53275 以下为原文(发表自linuxsir.com): 大部分转自红旗 ...

  8. 无需真人出镜,新手小白推荐这3个方法,做影视剪辑每天200+

    很多新手小白都想做短视频自媒体赚钱,又不敢真人出镜. 做影视剪辑账号又担心内容重复度过高导致过不了原创,严重的会封号.限流,这些大可不必担心. 各种各样的问题困扰着他们,所以开始纠结要不要做影视剪辑账 ...

  9. Spring.NET学习笔记10——方法的注入(基础篇) Level 200

    多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...

最新文章

  1. 前方高能 | 容器化应用操作原来可以这样简单
  2. [转]项目经理面试指南
  3. BZOJ 3119 Book (贪心+数学推导)
  4. mdkstc系列器件支持包下载_WPS Office 2019 For Linux(2020/10/21)更新-支持PDF编辑
  5. 如何动态创建asp.net 用户控件
  6. sqlalchemy连接mysql数据库_史上超详细的flask_sqlalchemy连接mysql数据库
  7. 7. JavaScript HTML DOM - 改变 CSS
  8. Linux 如何从网上下载文件
  9. 云服务商拿来主义或大限将至,Elastic 表示将变更开源许可协议并进行诉讼
  10. 新手如何学电影解说剪辑全教程
  11. IFrame里面的子页面html内容变化时,怎么动态改变IFrame的高度
  12. php 12306查询结果,使用php怎么编写一个12306余票查询功能
  13. C# Excel 新建工作表,新增工作表,更改工作表的名字
  14. 油画的发展过程经历了几个时期?
  15. 最近看的几部不错的电影
  16. 吴晓华当选河北省衡水市市长
  17. vue+vant 实现移动端问卷答题
  18. 火灾(火焰)数据集链接
  19. scratch模拟流星划过夜空的动画/少儿编程scratch教研教案课件课程素材脚本
  20. MapReduce之起源篇

热门文章

  1. 中基鸿业30岁女性的理财之道
  2. Python 让蔡徐坤在我的命令行里打篮球!| 技术头条
  3. Threejs3D炫酷地图
  4. 用Python爬取大众点评数据,推荐火锅店里最受欢迎的食品
  5. Java 查询英雄联盟玩家战绩
  6. service network restart重启失败
  7. php分页显示类——在线拍卖行(1)
  8. 2018WordPress本地头像加速
  9. 【教程】8K影像下如何玩转4K视频?
  10. 关于网站后台KindEditor编辑器存在安全漏洞