JNDI(Java Naming and Directory Interface)的中文意思是Java命名和目录接口。
借助于JNDI ,开发者能够通过名字定位用户,机器,网络,对象,服务。 JNDI的常见功能有定位资源,如定位到内网中一台打印机,定位Java对象或RDBMS(关系型数据库管理系统)等
在EJB,RMI,JDBC等JavaEE(J2EE)API技术中JNDI得到了广泛应用。JNDI为J2EE平台提供了标准的机制,并借助于名字来查找网络中的一切对象。
理解“命名和目录服务”
在掌握JNDI之前,开发者必须理解命名和目录服务。
名字类似于引用,即能标识某实体如对象,人等。在企业应用中,经常需要借助于名字实现对各种对象的引用,如借助于名字引用电话号码,IP地址,远程对象等。
命名服务类似于话务员,如果需要打电话给某人,但又不知道他的电话号码,于是将电话打到查询台,以便能够询问到用户的电话号码,打电话者需要提供人名给他。随后,话务员就能查到那人的电话号码。
命名服务的功能
将名字与对象绑定在一起,这类似于电话公司提供的服务,比如将人名绑定到被叫端的电话。
提供根据名字查找对象的机制。这称为查找对象或者解析名字。这同电话公司提供的服务类似,比如根据人名查找到电话号码。
在现实的计算机环境中,命名服务很常见,如需要定位网络中的某台机器,则借助于域名系统(Domain Name System,DNS)能够将机器名转化成IP地址。
目录对象和目录服务
在命名服务中,借助名字能够找到任何对象,其中有一类对象比较特殊,它能在对象中存储属性,它们被称之为目录对象或称之为目录入口项(Directory Entry)。将目录对象连接在一起便构成了目录(Directory),它是一个树状结构的构成,用户可以通过节点和分支查找到每个目录对象。
目录服务是对命名服务的扩展,它能够依据目录对象的属性而提供目录对象操作。
JNDI的概念和主要用途
为实现命名和目录服务,基于java的客户端需要借助于JNDI系统,它为命名和目录服务架起了通信的桥梁。JNDI的主要用途有:
开发者使用JNDI,能够实现目录和Java对象之间的交互。
使用JNDI,开发者能获得对JAVA事务API中UserTransaction接口的引用。
借助于JNDI,开发者能连接到各种资源工厂,如JDBC数据源,Java消息服务等。
客户和EJB组件能够借助于JNDI查找到其他EJB组件。
名字,绑定和上下文的概念
JNDI中存在多种名字,一种是原子名,如src/com/sitinspring中的src,com和sitinspring;一种是复合名,它由0个或多个原子名构成,如src/com/sitinspring。
绑定就是将名字和对象关联起来的操作。如system.ini绑定到硬盘中的文件, src/com/sitinspring/.classpath分别绑定到三个目录和一个文件。
上下文(Context)由0个或多个绑定构成,每个绑定存在不同的原子名。如WEB-INF文件夹下分别含有.cvsignore和web.xml的文件名。在JNDI中, WEB-INF是上下文,它含有原子名.cvsignore和web.xml的绑定,它们分别绑定到硬盘中的文件。
上下文中也允许存在上下文,它们被成为子上下文(subcontext),子上下文和上下文类似,它也能含有多个名字到对象的绑定。这类似于文件夹下含有子文件夹。
命名系统和初始上下文
命名系统由一套连在一起的上下文构成,而且这些上下文使用了相同的命名语法。可以用目录树来类比这个概念。
浏览命名空间的起点称之为初始上下文(Initial Context),初始上下文类似于目录树中的根节点概念。
借助于初始上下文,能够开始命名和目录服务。
JNDI查找资源示例
try {
Context initCtx = new InitialContext();
// java:comp/env是命名空间,相当于是本机JNDI资源引用根目录
Context envCtx = (Context) initCtx.lookup("java:comp/env");
Member bean = (Member) envCtx.lookup("Member");
System.out.print("member name=" + bean.getMemberName() + " age="
+ bean.getAge());
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JNDI有关API
list():用于获得当前上下文的绑定列表
lookup():用于解析上下文中名字绑定,该操作将返回绑定到给定名字的对象。
rename():重新命名
createSubContext():从当前上下文创建子上下文。
destroySubContext():从当前上下文销毁子上下文。
bind()。从当前上下文中创建名字到对象的绑定。
rebind():再次绑定,如果已经存在同名绑定则覆盖之。