JNDI(Java Naming And Directory Interface),這是一套查詢和訪問命名和目錄的接口規(guī)范.
命名
我們假設(shè)有一個哈希表,命名就是它的key,key是一個字符串,而它的value是一個對象.我們可以用bind來綁定命名和對象,也可以用lookup來根據(jù)命名獲取對象.
目錄
目錄我們可以理解成這張hash表的名字.我們可以通過Context.PROVIDER_URL來設(shè)置.
規(guī)范的實(shí)現(xiàn)者
前面我們講到JNDI是一套規(guī)范,以下是它的實(shí)現(xiàn)者:
DNS、XNam 、Novell目錄服務(wù)、LDAP(Lightweight Directory Access Protocol 輕型目錄訪問協(xié)議)、 CORBA對象服務(wù)、文件系統(tǒng)、Windows XP/2000/NT/Me/9x的注冊表、RMI、DSML v1&v2、NIS
實(shí)現(xiàn)者的區(qū)別
我們可以用參數(shù)Context.INITIAL_CONTEXT_FACTORY來指定是用哪個實(shí)現(xiàn)者.我們可能有個疑問,都是用來操作哈希表,為什么還要分不同的實(shí)現(xiàn)者呢?
- 不同的實(shí)現(xiàn)者自身已經(jīng)綁定了一些可用的命名和對象,我們可以直接拿來用
- 不同實(shí)現(xiàn)者綁定命名和對象的方式可能會有些許不同
<?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");來獲取一個數(shù)據(jù)源對象.這個例子也從側(cè)面說明JNDI的一個好處,以前我們配置數(shù)據(jù)庫相關(guān)參數(shù)都是在代碼里面寫死的,現(xiàn)在我們可以把它配置在XML文件里面,然后用JNDI引用.這樣子方便上線后仍能修改配置文件,而且使代碼更加簡潔.
RMI實(shí)現(xiàn)者的簡單例子
綁定代碼:
//注冊rmi端口
LocateRegistry.createRegistry(1099);
//配置實(shí)現(xiàn)者參數(shù)
Hashtable env = new Hashtable();
//配置實(shí)現(xiàn)者的類型
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
//配置目錄
env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
//創(chuàng)建容器
InitialContext ctx = new InitialContext(env);
//綁定命名和對象
ctx.bind("HelloService", new HelloServiceImpl());
獲取代碼:
//配置實(shí)現(xiàn)者參數(shù)
Hashtable env = new Hashtable();
//配置實(shí)現(xiàn)者的類型
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
//配置目錄
env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
//創(chuàng)建容器
Context ctx = new InitialContext(env);
//根據(jù)命名獲取對象
HelloService helloService = (HelloService) ctx.lookup("HelloService");
//做事
helloService.say("haha");
以上即本人對JNDI的理解,如果錯誤,麻煩指正.