一、JNDI是什么?
JNDI--Java 命名和目錄接口(Java Naming and Directory Interface),是一組在Java應用中訪問命名和目錄服務的API。
二、JNDI好處
解耦:通過注冊、查找JNDI服務,可以直接使用服務,而無需關心服務提供者,這樣程序不至于與訪問的資源耦合!
JNDI優點
包含了大量的命名和目錄服務,使用通用接口來訪問不同種類的服務;
可以同時連接到多個命名或目錄服務上;
建立起邏輯關聯,允許把名稱同Java對象或資源關聯起來,而不必知道對象或資源的物理ID。
JNDI程序包:
javax.naming:命名操作;
javax.naming.directory:目錄操作;
javax.naming.event:在命名目錄服務器中請求事件通知;
javax.naming.ldap:提供LDAP支持;
javax.naming.spi:允許動態插入不同實現。
利用JNDI的命名與服務功能來滿足企業級APIs對命名與服務的訪問,諸如EJBs、JMS、JDBC 2.0以及IIOP上的RMI通過JNDI來使用CORBA的命名服務。
三、JNDI架構與原理
相比較架構與原理,更關注與使用,故略!
四、JNDI使用
在J2EE容器(如weblogic、websphere、jboss等)中使用:
在weblogic環境下查找tuxedo 連接
1
|
2
3
|
//在weblogic環境查找tuxedo連接 Context ctx = new InitialContext(); TuxedoConnectionFactory tuxedoFactory = (TuxedoConnectionFactory) ctx.lookup( "tuxedo.services.TuxedoConnection" ); |
在web容器查找數據源
1
|
2
|
Context ctx= new InitialContext(); DataSource ds=(Datasource)ctx.lookup( "java:comp/env/jdbc/mydatasource" ); |
重點關注Context ctx = new InitialContext(),上面的代碼在容器下能夠很好的工作,尤其是查找數據源的代碼,無論是在tomcat,還是在weblogic、jboss,但如果脫離了容器,我們將得到異常“NoInitialContextException”,這是為什么呢?
原因很簡單,就是不存在相關的context,其本質是JNDI的服務提供者環境,即誰將提供此環境!
為了能夠使上面的代碼工作,我們需要使用帶參的構造子InitialContext(Hashtable),指定JNDI服務提供者環境信息,以weblogic環境為例:
1
|
2
3
4
|
Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ); env.put(Context.PROVIDER_URL, " t3://localhost:7001 " ); InitialContext ctx = new InitialContext(env); |
但上面的代碼不適合WebSphere、jboss等環境,原因在于所需環境信息不同,那么,Context ctx = new InitialContext()是如何做到在各個j2ee容器下有效地呢?原因在于這個默認的構造子是從System.properties讀取相關的環境信息的,由此不難猜出在各種J2EE容器下,如weblogic、jboss,它們都自己為自己設置了相應的信息!下面是一個關于System.properties設置JNDI服務環境的例子:
1
|
2
3
|
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ); System.setProperty(Context.PROVIDER_URL, " t3://localhost:7001 " ); InitialContext ctx = new InitialContext(); |
五、借助Spring完成JNDI查找
對于手頭的weblogic,給出常用的兩個查找例子,做個備忘吧!
查找tuxedo connnection:
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< bean id = "tuxedoConnFactory" class = "org.springframework.jndi.JndiObjectFactoryBean" > < property name = "jndiName" > < value >tuxedo/services/TuxedoConnection</ value > </ property > < property name = "resourceRef" > < value >false</ value > </ property > < property name = "jndiEnvironment" > < props > <!-- The value of ContextPROVIDER_URL --> < prop key = "java.naming.provider.url" > t3://localhost:7001 </ prop > < prop key = "java.naming.factory.initial" >weblogic.jndi.WLInitialContextFactory</ prop > </ props > </ property > </ bean > |
查找DataSource:
1
|
2
3
4
5
|
< bean id = "tuxedoConnFactory" class = "org.springframework.jndi.JndiObjectFactoryBean" > < property name = "jndiName" > < value >java:comp/env/jdbc/myDatasource</ value > </ property > </ bean > |