JNDI(Java Naming And Directory Interface),这是一套查询和访问命名和目录的接口规范.
命名
我们假设有一个哈希表,命名就是它的key,key是一个字符串,而它的value是一个对象.我们可以用bind来绑定命名和对象,也可以用lookup来根据命名获取对象.
目录
目录我们可以理解成这张hash表的名字.我们可以通过Context.PROVIDER_URL来设置.
规范的实现者
前面我们讲到JNDI是一套规范,以下是它的实现者:
DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS
实现者的区别
我们可以用参数Context.INITIAL_CONTEXT_FACTORY来指定是用哪个实现者.我们可能有个疑问,都是用来操作哈希表,为什么还要分不同的实现者呢?
- 不同的实现者自身已经绑定了一些可用的命名和对象,我们可以直接拿来用
- 不同实现者绑定命名和对象的方式可能会有些许不同
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MySqlDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/lw</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>rootpassword</password>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
比如这种xml配置文件也是一种绑定命名和对象的方式,我们可以用DataSource ds=(Datasource)ctx.lookup("java:MySqlDS");
来获取一个数据源对象.这个例子也从侧面说明JNDI的一个好处,以前我们配置数据库相关参数都是在代码里面写死的,现在我们可以把它配置在XML文件里面,然后用JNDI引用.这样子方便上线后仍能修改配置文件,而且使代码更加简洁.
RMI实现者的简单例子
绑定代码:
//注册rmi端口
LocateRegistry.createRegistry(1099);
//配置实现者参数
Hashtable env = new Hashtable();
//配置实现者的类型
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
//配置目录
env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
//创建容器
InitialContext ctx = new InitialContext(env);
//绑定命名和对象
ctx.bind("HelloService", new HelloServiceImpl());
获取代码:
//配置实现者参数
Hashtable env = new Hashtable();
//配置实现者的类型
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
//配置目录
env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
//创建容器
Context ctx = new InitialContext(env);
//根据命名获取对象
HelloService helloService = (HelloService) ctx.lookup("HelloService");
//做事
helloService.say("haha");
以上即本人对JNDI的理解,如果错误,麻烦指正.
网友评论