1、什么是jndi

JavaNaming and Directory Interface,用于定位查找服务对象,内部是以一种树状的目录结构,如下图:

java规范之jndi-编程之家


2、使用jndi有哪些好处?

jndi将一些关键信息放到内存中,可以提高访问效率;通过jndi可以达到解耦的目的,是连接不同对象的有利纽带。

3、什么时候使用jndi?

jndi是一种查找服务,用于查找:
web应用环境变量
EJBs和他们的环境变量
通过DataSource的数据库连接池
JMS目标和连接工厂
其他服务


4、使用jndi的注意事项:
不要将jndi当做数据库使用
jndi对象存储在内存中
访问jndi对象与网络性能有关


5、jndi的常用方法有哪些?

使用bind、rebind方法进行绑定

使用unbind方法解除绑定
使用lookup方法查找
使用InitialContext方法初始化,可以包含参数,不包含参数的时候使用默认值

远程绑定对象必须是序列化的,访问命名服务是,对象采用的是复制机制,也就是值的复制

如果使用本地对象,使用的是变量的引用。

6、连接jndi的几种方法:

1.从服务器端连接到JNDI:默认当前,返回一个context。

//创建一个InitialContext
context ctx= new InitialContext();


2.从任何一个地反连接到jndi:需要先设置环境:

//创建Environment对象
weblogic.jndi.Enviroment env = new weblogic.jndi.Enviroment();
//填写Environment
//weblogic server的位置
env.setProviderurl("t3://127.0.0.1:7011");env.setSecurityPrincipal("System");
//安全信息
env.setSecurityCredenttials("PassWord");//使用Environment对象创建InitialContext
context ctx =env.getInitialContext();


3.使用hash类链接jndi:

Hashtble env = new Hashtble();
Env.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
Env.put(Context.PROVIDER_URL,"T3://LOCALHOST:7001");
Evn.put(Context.SECURITY_PRINCIPAL,"system");
Env.put(Cotext.SECURIRY_CRRDENTIALS,"PassWord");
//此处有三种构造函数
Context ctx = new InitialContext(env);


4.使用Hardcoded名和Properties类:

Properties env = new Properties();
env.setProperty("java.naming,factory,initial","weblogic.jndi.WLInitialContextFactory");
env.setProperty("java.naming.provider.url","t3:192.2.256.102:7001");
env.setproperty("java.naming.securiry.principal","system");
env.setProperty("java.naming.security.credentials","PaSsWoRd");
Context ctx = new InitialContext(env);


7、使用默认值:

jndi.properties文件为所有的Initial Contexts设置默认属性,且文件的的搜索次序为:
CLASSPATH其次是$JAVA_HOME/lib/
示例:

Java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory;
Java.naming.provider.url=t3://localhost:7001;
Java.naming.security.principal =system;
Java.naming.security.credentials =password;
//没有参数,使用这些默认值
Context ctx = new InitialContext();


8、创建一个用于绑定对象的新Subcontext:

//创建Environment对象
Context ctx =env.getInitialContext();//首先必须获得存在的Subcontext或InitialContext
//填写Environment
Context subcontext =ctx.createSubcontext("newSbucontext");//在当前的Context下创建新的Subcontext
subcontext.rebind("boundObject",object);//绑定一个对象//当结束时经常关闭访问的资源
subcontext.close();
ctx.close();


9、JNDI查找对象:

从JNDI查找对象,反序列化后,使用事务(多分支的事务),Lookup()从JNDI树获得对象。

import javax.naming.*;
try{Context ic = new Context();Object obj;//查找对象obj = ic.lookup("javax.transaction.UserTransaction");//反序列化和事务UserTransaction ut = (UserTransaction)obj;ut.begin();//分支事务…………	ic.close();
}catch(NamingException e ){……………………}


10、远程绑定:

在客户端使用的时候需要反序列化,传送到服务端的时候是序列化的。一个Binding示例:

public static Context getInitialContext() throws NamingException{Environment env = new Environment();env.setProviderUrl("t3://localhost:7001");env.setSecurityPrincipal("system");env.setSecurityCredendtials("weblogic");Context context = env.getInitialContext();return context;
}
//获得initial contex
Context ctx = getInitialContext();
//创建名为Bank的对象
Bank myBank = new Bank();
//把对象绑定到JNDI树
ctx.rebind("theBank",myBank);
ctx.close();


11、Un-Binding示例:

public static Context getInitialContext() throws NamingException{Environment env = new Environment();env.setProviderUrl("t3://localhost:7001");env.setSecurityPrincipal("system");env.setSecurityCredendtials("weblogic");Context context = env.getInitialContext();return context;
}
//获得initial contex
Context ctx = getInitialContext();
//创建名为Bank的对象
Bank myBank = new Bank();
//解除绑定
ctx.unbind("theBank");
ctx.close();


12、使用jndi可能的异常:

AuthenticationException
CommunicationException 
InvalidNameException
NameNotFoundException
NoInitialcontextException

如果能够理解jndi的原理,这些异常是不必深究。

总结:

 jndi是J2EE的一个非常重要的标准,这里重点总结了连接jndi的几种方法以及通过jndi查找远程对象的方法(lookup)以及针对jndi树的常见的操作:添加subcontext、绑定、接触绑定的方法。

学习jndi是学习ejb开发的一个基础。