Java 升级之路(五)JNDI

 


Java 升级之路(五)JNDIJNDI简介ContextJNDI调用JNDI用法实例JNDI结构常用的JNDI操作

JNDI简介

Java命名和目录接口(Java Naming and Directory Interface,缩写JNDI),是Java的一个目录服务应用程序接口(API),通过名称将资源与服务进行关联。

(模仿Windows注册表

JNDI包括Naming ServiceDirectory Service

Naming Service(命名服务):是将名称与值相关联的实体,称为绑定。它提供了一种使用findsearch操作来根据名称查找对象的便捷方式。 通过名称去获取对应的服务。

Directory Service(目录服务):是一种特殊的Naming Service,它允许存储和搜索目录对象,一个目录对象不同于一个通用对象,目录对象可以与属性关联,因此,目录服务提供了对象属性进行操作功能的扩展。用类似目录的方式来存取服务。

命名服务可以理解类似于HashTable<K,V> pair的方式去查找调用资源的。Key就是名字,Value则是资源。命名服务是利用key获取到value

目录服务则是通过描述这项资源,来得到对应的名字来调用这项服务。

Key 键名Value 数据
字符串JNDI中存的是对象

JNDI服务可以:访问文件系统中的文件、定位远程RMI注册的对象,访问LDAP这样的目录服务等等。

 

光看概念不是好理解,下面看看怎么用JNDI

Context

JNDI中需要用到Context

Contextjava中译为上下文,是用来存储系统的一些初始化信息

实际上Context所代表的意义是一些:公用信息、环境、容器等

 

JNDI调用

JNDI客户端调用方式:

一些常见的JNDI name的例子:

JNDI的查找一般使用lookup()方法如registry.lookup(jndiName)

JNDIRMI配合使用(后面还有详细的脚本,这里手动设置了对应服务的工厂以及对应服务的PROVIDER_URL):

INITIAL_CONTEXT_FACTORY的值用于指定Name Service Provider Factory

在使用JNDI之前,需要先获取JNDI的提供者,并在系统注册它。

JNDI相关的系统属性在javax.naming.Context中定义,常用的属性:

对于目录服务,由于一般需要安全设置,还通常使用:

注册方式:使用System.setProperty注册,如果程序不显示说明,java会在classpath内查找jdni.properties文件来完成注册。

使用方式:命名服务InitialContext开始,目录服务则使用InitialDirContext。它们分别实现了ContextDirContext,这两个接口分别对应命名服务目录服务的接口,也是JNDI中最重要的两个接口。

 

JNDI用法实例

上面JNDI与RMI配合使用的脚本是将Server.javaClient.java合在一起并且手动设置了对应服务的工厂以及对应服务的PROVIDER_URL

Server.java:

Client.java:

SecretImpl.java:

Secret.java:

运行Server后再执行Client可以获取到Some_secret_data

 

 

JNDI结构

第一层: Java 应用,访问JNDI的代码;

第二层: JNDI API :统一的命名和目录服务接口

第三层: Naming Manager : JNDI 管理器

第四层: JNDI SPI (Server Provider Interface ) :用于构建 JNDI 实现的框架,能够动态的插入命名和目录服务提供商的产品;

第五层:命名和目录服务提供商的产品,例如:LDAP, DNS, NIS, NDS, RMI 等

在SPI级别,JVM将允许从远程代码库加载类并实施安全性。管理器的安装取决于特定的提供程序(例如在上面说到的RMI那些利用方式就是SPI级别,必须设置安全管理器):

ProviderProperty to enable remote class loading是否需要强制安装Security Manager
RMIjava.rmi.server.useCodebaseOnly = false (JDK 6u45、JDK 7u21之后默认为true)需要
LDAPcom.sun.jndi.ldap.object.trustURLCodebase = true(default = false)非必须
CORBA 需要

但是,在Naming Manager层放宽了安全控制。解码JNDI命名时始终允许引用从远程代码库加载类,而没有JVM选项可以禁用它,并且不需要强制安装任何安全管理器,例如上面说到的命名引用那种方式。

 

常用的JNDI操作

void bind(String sName,Object object);―― 绑定:把名称同对象关联的过程 void rebind(String sName,Object object);―― 重新绑定:用来把对象同一个已经存在的名称重新绑定 void unbind(String sName);―― 释放:用来把对象从目录中释放出来 lookup(String name);―― 查找:返回目录总的一个对象 void rename(String sOldName,String sNewName);―― 重命名:用来修改对象名称绑定的名称 NamingEnumeration listBinding(String sName);―― 清单:返回绑定在特定上下文中对象的清单列表 NamingEnumeration list(String sName);―― 清单:返回绑定在特定上下文中对象的清单列表