`

InitialContext和lookup

阅读更多
最近因为工作需要开始学习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;  
    }  


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);  
    }  


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);

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

分享到:
评论
3 楼 jerry.zhao 2016-10-27  
ybzshizds 写道
这种用工厂模式解决的办法其实还是有一个问题,就是ejb容器重启后,客户端应该也要重新去new InitialContext,否则用原来的InitialContext去lookup,会抛出错。

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

...



// 缓存Context
private static Context context = initContext();

private static Context initContext() {
try {
Properties properties = new Properties();
properties.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url", getRemoteUrl());
Context context = new InitialContext(properties);
return context;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 根据指定的jndi实例化bean
*
* @param jndi
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String jndi) {
try {
Object bean = context.lookup(jndi);
return (T) bean;
} catch (Exception e) {
// 当异常时,可能目标服务器重启过,需要重新初始化context
context = initContext();
try {
Object bean = context.lookup(jndi);
return (T) bean;
} catch (Exception e1) {
e.printStackTrace();
throw new RuntimeException(e1);
}
}
}
2 楼 surpassno 2013-08-29  
1 楼 ybzshizds 2010-08-06  
这种用工厂模式解决的办法其实还是有一个问题,就是ejb容器重启后,客户端应该也要重新去new InitialContext,否则用原来的InitialContext去lookup,会抛出错。

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

为每个ejbhome,新建一个ejbHelper类

如:


package com.company.vas.ejb.helper;

import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.naming.NamingException;

import com.company.util.Log;
import com.company.vas.ejb.Invoice;
import com.company.vas.ejb.home.InvoiceHome;

public class InvoiceHelper {

    private static final String CLASS_NAME = "InvoiceHelpler";
    private static InvoiceHome home;

    public static Invoice getInvoice() {
	try {
	    if (home == null) {
		home = (InvoiceHome) EjbGetter.getEJBHome(
						IInvoice.JNDI_NAME, InvoiceHome.class);
	     }
	     return home.create();
	} catch (NamingException e) {
			Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
			home = null;
	} catch (RemoteException e) {
			Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
			home = null;
	} catch (CreateException e) {
			Log.error(CLASS_NAME, "getInvoice()", e.getMessage());
			home = null;
	}
	   return null;
	}
}


package com.company.vas.ejb.helper;

import java.util.Properties;

import javax.ejb.EJBHome;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EjbGetter {

	public static EJBHome getEJBHome(String service_jndiname, Class homeInterface) throws NamingException{
		Properties env = new Properties();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
		env.put(Context.PROVIDER_URL, "192.168.60.120:1099");
		env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
	
		Context ic = new InitialContext(env);
	    EJBHome ejbHome = (EJBHome)javax.rmi.PortableRemoteObject.narrow(ic.lookup(service_jndiname), homeInterface);
		
		return ejbHome;
	}
}

相关推荐

    JNDI注入学习1

    JNDI 注简单来说就是在 JNDI 接在初始化时,如: InitialContext.lookup(URI) ,如果URI 可控,那么客户端就可能会被攻击通过

    JNDI连接数据库配置

    JNDI连接数据库配置,Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("jdbc/DevDB"); Connection conn = ...

    Java EJB简单例子.rar

     InitialContext jndiContext = new InitialContext(properties);  //取得Home对象的引用  Object ref = jndiContext.lookup("HelloWorldHome");  HelloWorldHome home = (HelloWorldHome)  ...

    EJB HelloWorld

    InitialContext ctx = new InitialContext(props); HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote"); out.println(helloworld.SayHello("佛山人")); 5.用ant或eclipse,把...

    Java Jndi数据连接池,sql2000或者sql2005数据库

    DataSource source = (DataSource) ic.lookup("java:comp/env/jdbc/jndidemo"); dbcon = source.getConnection(); 需要导的包 import javax.naming.Context; import javax.naming.InitialContext; import ...

    JDBC详解HTML-JDBC.pp

    Context ctx = (Context) new InitialContext().lookup("java:comp/env"); DataSource ds = (DataSource) ctx.lookup(jndi); Connection cn = ds.getConnection(); 3&gt;.执行sql语句(Execute the SQL) &lt;1&gt;.用...

    “E-家园”个人网站

    Context ic = new InitialContext(); DataSource source = (DataSource) ic. lookup("java:comp/env/jdbc/ownHome"); conn = source.getConnection(); } catch (Exception e) { throw new DBAccessException("不能...

    java连接数据库工具类--DBConnection(java源码)

    DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/" + jndiName); return dataSource.getConnection(); } catch (NamingException ex) { ex.printStackTrace(); } catch ...

    java设计模式CatalogDAOFactory是典型的工厂方法

     InitialContext ic = new InitialContext();  //动态装入CATALOG_DAO_CLASS  //可以定义自己的CATALOG_DAO_CLASS,从而在无需变更太多代码  //的前提下,完成系统的巨大变更。  String className =(String) ...

    jboss-as-7.1.1.Final

    Object obj = context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/HelloWorld!com.ejb.HelloWorldRemote"); HelloWorldRemote hwr = (HelloWorldRemote)obj; String say = hwr.sayHello...

    hibernate.properties

    #hibernate.transaction.manager_lookup_class org.hibernate.transaction.WebSphereTransactionManagerLookup #hibernate.transaction.manager_lookup_class org.hibernate.transaction....

    二十三种设计模式【PDF版】

    由于建筑受材料和功用以及费用的影响,所用模式种类不多,这点是和软件很大的不同. 正因为这点不同,导致建筑的管理模式和软件的管理模式就有很多不同, 有些人认识不到这点,就产生了可以大量使用"软件 蓝领"的想法,...

    jsp连接池成功之例

    } DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/mysql"); if(ds==null) {throw new Exception("没有匹配数据库"); } con=ds.getConnection(); &lt;br&gt; sql=con....

Global site tag (gtag.js) - Google Analytics