Java命名和目录接口,是一组在Java应用中访问命名和目录服务的API。为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。
命名服务将名称和对象联系起来,可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称还有属性。
一、命名服务与目录服务
命名服务:作为一种基础设施出现在众多的计算机系统,其意义在于提供根据名称关联对象和通过对象匹配相应的命名服务。命名服务允许你通过名称找到一个与之对应的对象。例如在Internet上的域名服务(domain namingservice,DNS)就是提供将域名映射到IP地址的命名服务,在打开网站时一般都是在浏览器中输入名字,通过DNS找到相应的IP地址,然后打开。
目录服务:是一种特殊类型的数据库,与SQLServer、Access、Oracle等关系数据库管理系统相反,构造目录服务的目的是为了处理基于行为的事务,并且使用一种关系信息模型。
目录服务将命名服务的概念进一步引申为提供具有层次结构的信息库,这一信息库除了包含一对一的关系外,还有信息的层次结构。对目录服务而言,这种层次结构通常用于优化搜索操作,并且也可以按实际情况进行分布或者跨网络复制。
目录服务是命名服务,命名服务不需要是目录服务。
命名和目录服务把标识符和资源关联起来。
二、JNDI架构
JNDI架构与JDBI架构非常类似。JNDI架构提供了一组标准命名系统的API。在应用程序中,我们实际上只是用以上几个包的种类。具体调用类以及通信过程对用户来说是透明的。JNDI API提供了访问不同JNDI服务的一个标准的统一实现,其具体实现可由不同的Service Provider来完成。
中间层为命名管理层。其功能应该由JNDI SPI来完成。
最下层为JNDI SPI API及其具体实现。
我们只需将服务端的相关参数传给JNDI API就可以了,具体调用过程由SPI来完成。
三、基本使用
1、注册JNDI提供者
使用之前,先获取JNDI提供者,并注册。
2、连接服务
注册之后,就可以实施服务连接了。对于名字服务由InitialContext开始,目录服务则使用InitialDirContext.它们分别实现了Context和DirContext,这两个接口是JNDI中最重要的两个接口
例如:
System.setProperty(Context.INITIAL_CONTEXT_FACTORY," com.sun.jndi.fscontext.FSContextFactory"); InitialContext ctx = new InitialContext();
3、查找对象
使用lookup查找对象,除了使用String作为参数外,还可以使用Name接口作为参数
importjavax.naming.*; try{ Context ic = new Context(); Objectobj; obj= ic.lookup("javax.transaction.UserTransaction"); UserTransactionut = (UserTransaction)obj; ut.begin(); ic.close(); }catch(NamingExceptione){}
4、远程绑定对象
例如:
public staticContext getInitialContext() throws NamingException{ Environment env = new Environment(); env.setProviderUrl("t3://localhost:7001"); env.setSecurityPrincipa("system"); env.setSecurityCredendtials("weblogic"); Contextcontext = env.getInitialContext(); returncontext; } //获得intial context Context ctx =getInitialContext(); //创建名为Band的对象 Bank myBank = newBank(); //对象绑定 ctx.bind("theBank",myBank); //把对象重新绑定到JNDI树 ctx.rebind("theBank",myBank); //解除绑定 ctx.unbind("theBank"); ctx.close();
5、对象改名
ctx.rename("report.txt", "old_report.txt");
6、获取属性
属性相关的接口是Attribute和Attributes,它们都在javax.naming.directory包内。通过DirContext的getAttributes方法就可以获得对象的属性集合,然后使用Attributes的get方法获得对应的属性,最后通过Attribute的get方法就可以获得属性值。
String dn = "uid=me, dc=mycompany, dc=com, ou=customer, o=ExampleApp"; Context user = (Context)ctx.lookup(dn); //获得所有属性 Attributes attrs = user.getAttributes(""); Attribute test= attrs .get("test"); Object testValue= test.get();
7、修改属性
使用DirContext和InitialDirContext的modifyAttributes方法完成。所谓的修改过程,实际就是先构造要修改的属性列表,然后使用上述方法提交。对于属性包含多个值时,需要把属性的不修改的值也要包含,否则服务器会认为那些值不再需要而删除它们。
public void updateAddress(String dn,String address, String country, String phone) { BasicAttributes mod_attrs = new BasicAttributes(); if(address != null) mod_attrs.put("address", address); if(country != null) mod_attrs.put("c", country); if(phone != null) mod_attrs.put("phonenumber", phone); if(mod_attrs.size() != 0) initial_ctx.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, mod_attrs);
总结
JNDI的思想是提供一个通用的接口。底层的名字服务时限可以是各种类型,JNDI通过SPI时限代码屏蔽了各种名字和目录服务实现的区别。
JNDI可以解决数据共享,分布式应用,紧耦合的问题,所以可以应用在一些比较大的软件开发中,分布式系统中或者是比较重视后期维护和升级的项目中。
这些是一些最基础的知识积累,推荐一下JNDI的扩展。
推荐地址:
J2EE总结:JNDI 主要介绍JNDI的作用
JNDI 侧重从LDAP的角度出发去介绍JNDI的属性,功能等
JNDI在J2EE中的角色 主要介绍JNDi环节企业级应用程序部署带来的负担,帮助应用程序从部署细节中解脱出来
Java华丽转身 —— J2EE规范(一) JNDI Java Naming and Directory Interface,布布扣,bubuko.com
Java华丽转身 —— J2EE规范(一) JNDI Java Naming and Directory Interface