看了好多博客,發現老是能把JNDI和數據庫連道一塊兒來說,固然說的也沒有錯,不過DB鏈接只是JNDI的一個很小很小的應用。查閱官方資料總結出下面的內容:html
JNDI即Java Naming and Directory Interface(JAVA命名和目錄接口),那麼java命名目的就是爲了記錄一些不方便記錄的內容,就像人的名字或DNS中的域名與IP的關係。java
一個命名的展現由名字和分隔符提現:mysql
例如:sql
一樣命名空間也是 數據庫
在上面的示例中,一個標識符最終都要綁定到具體的內容:例如/usr/hello綁定的是hello目錄;sales.wiz.com綁定的是x.x.x.x樣式的IP地址安全
JNDI由JNDI API、命名管理、JNDI SPI(service provider interface)服務提供的接口。咱們的應用能夠經過JNDI的API去訪問相關服務提供的接口。 服務器
咱們要使用JNDI,必需要有服務提供方,咱們經常使用的就是JDBC驅動提供數據庫鏈接服務,而後咱們配置JNDI鏈接。。 併發
JDK也爲咱們提供了一些服務接口: oracle
1. LDAP (Lightweight Directory Access Protocol) 輕量級目錄訪問協議 ide
2. CORBA (Common Object Request Broker Architecture) 公共對象請求代理結構服務
3. RMI(Java Remote Method Invocation)JAVA遠程遠程方法調用註冊
4. DNS(Domain Name Service)域名服務
JNDI並非與數據源鏈接綁定在一塊兒的。從數據源鏈接認識JNDI,可是認識完JNDI後,必定要跳出來,JNDI是一個命名目錄接口,提供與外界的一個訪問關係,只要相關應用、設備能提供服務,那麼咱們就能夠經過JNDI來鏈接處理。
例如:鏈接打印機、鏈接註冊表等。
更多的應用要本身來探索。
地址:http://blog.csdn.net/zjlolife/article/details/8881154
總結:
J2EE 規範要求全部 J2EE 容器都要提供 JNDI 規範的實現。//sun 果真喜歡制定規範JNDI 在 J2EE 中的角色就是「交換機」 —— J2EE 組件在運行時間接地查找其餘組件、資源或服務的通用機制。在多數狀況下,提供 JNDI 供應者的容器能夠充當有限的數據存儲,這樣管理員就能夠設置應用程序的執行屬性,並讓其餘應用程序引用這些屬性(Java 管理擴展(Java Management Extensions,JMX)也能夠用做這個目的)。JNDI 在 J2EE 應用程序中的主要角色就是提供間接層,這樣組件就能夠發現所須要的資源,而不用瞭解這些間接性。
在 J2EE 中,JNDI 是把 J2EE 應用程序合在一塊兒的粘合劑,JNDI 提供的間接尋址容許跨企業交付可伸縮的、功能強大且很靈活的應用程序。這是 J2EE 的承諾,並且通過一些計劃和預先考慮,這個承諾是徹底能夠實現的。
從上面的文章中能夠看出:
一、JNDI 提出的目的是爲了解藕,是爲了開發更加容易維護,容易擴展,容易部署的應用。
二、JNDI 是一個sun提出的一個規範(相似於jdbc),具體的實現是各個j2ee容器提供商,sun 只是要求,j2ee容器必須有JNDI這樣的功能。
三、JNDI 在j2ee系統中的角色是「交換機」,是J2EE組件在運行時間接地查找其餘組件、資源或服務的通用機制。
四、JNDI 是經過資源的名字來查找的,資源的名字在整個j2ee應用中(j2ee容器中)是惟一的。
地址:http://blog.csdn.net/kingmax54212008/article/details/52229642
一、 首先程序代碼獲取初始化的 JNDI 環境而且調用 Context.lookup() 方法從 JNDI 服務提供者那裏獲一個 DataSource 對象
二、 中間層 JNDI 服務提供者返回一個 DataSource 對象給當前的 Java 應用程序這個 DataSource 對象表明了中間層服務上現存的緩衝數據源
三、 應用程序調用 DataSource 對象的 getConnection() 方法
四、 當 DataSource 對象的 getConnection() 方法被調用時,中間層服務器將查詢數據庫 鏈接緩衝池中有沒有 PooledConnection 接口的實例對象。這個 PooledConnection 對象將被用於與數據庫創建物理上的數據庫鏈接
五、 若是在緩衝池中命中了一個 PooledCoonection 對象那麼鏈接緩衝池將簡單地更 新內部的緩衝鏈接隊列並將該 PooledConnection 對象返回。若是在緩衝池內沒 有找到現成的 PooledConnection 對象,那麼 ConnectionPoolDataSource 接口將會被 用來產生一個新的 PooledConnection 對象並將它返回以便應用程序使用
6。 中間層服務器調用 PooledConnection 對象的 getConnection() 方法以便返還一個 java.sql.Connection 對象給當前的 Java 應用程序
七、 當中間層服務器調用 PooledConnection 對象的 getConnection() 方法時, JDBC 數據 庫驅動程序將會建立一個 Connection 對象而且把它返回中間層服務器
八、 中間層服務器將 Connection 對象返回給應用程序 Java 應用程序,能夠認爲這個 Connection 對象是一個普通的 JDBC Connection 對象使用它能夠和數據庫創建。事 實上的鏈接與數據庫引擎產生交互操做 。
九、 當應用程序不須要使用 Connection 對象時,能夠調用 Connection 接口的 close() 方 法。請注意這種狀況下 close() 方法並無關閉事實上的數據庫鏈接,僅僅是釋 放了被應用程序佔用的數據庫鏈接,並將它還給數據庫鏈接緩衝池,數據庫鏈接 緩衝池會自動將這個數據庫鏈接交給請求隊列中下一個的應用程序使用。
在DataSource中事先創建多個數據庫鏈接,保存在數據庫鏈接池中。當程序訪問數據庫時,只用從鏈接池中取空閒狀態的數據庫鏈接便可,訪問結束,銷燬資源,數據庫鏈接從新回到鏈接池,這與每次去直接訪問數據庫相比,會節省大量時間和資源。
JNDI( Java Naming and Directory Interface ),是Java平臺的一個標準擴展,提供了一組接口、類和關於命名空間的概念。如同其它不少Java技術同樣,JDNI是provider-based的技術,暴露了一個 API和一個服務供應接口(SPI)。這意味着任何基於名字的技術都能經過JNDI而提供服務,只要JNDI支持這項技術。JNDI目前所支持的技術包括 LDAP、CORBA Common Object Service(COS)名字服務、RMI、NDS、DNS、Windows註冊表等等。不少J2EE技術,包括EJB都依靠JNDI來組織和定位實體。能夠把它理解爲一種將對象和名字捆綁的技術,對象工廠負責生產出對象,這些對象都和惟一的名字綁在一塊兒,外部資源能夠經過名字得到某對象的引用。
在javax.naming的包包中提供Context接口,提供了兩個很好用的方法:
<1> void bind( String name , Object object )
將名稱綁定到對象。全部中間上下文和目標上下文(由該名稱最終原子組件之外的其餘全部組件指定)都必須已經存在。
<2>Object lookup( String name )
檢索指定的對象。若是 name爲空,則返回此上下文的一個新實例(該實例表示與此上下文相同的命名上下文,但其環境能夠獨立地進行修改,並且能夠併發訪問)。
Context.xml方式:
<Resource name="jdbc/MySQL" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="60" wait_timeout="18800" timeBetweenEvictionRunsMillis="300000" minEvictableIdleTimeMillis="600000" username="root" password="jdzxdb" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/sxtele?comautoReconnect=true&failOverReadOnly=false" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/> <Resource name="jdbc/db2" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="60" wait_timeout="18800" timeBetweenEvictionRunsMillis="300000" minEvictableIdleTimeMillis="600000" username="lcgluser" password="lcgluser" driverClassName="com.ibm.db2.jcc.DB2Driver" url="jdbc:db2://133.64.46.65:50000/STEDWDB" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/>
name 表示指定的jndi名稱
auth 表示認證方式,通常爲Container
type 表示數據源牀型,使用標準的javax.sql.DataSource
maxActive 表示鏈接池當中最大的數據庫鏈接
maxIdle 表示最大的空閒鏈接數
maxWait 當池的數據庫鏈接已經被佔用的時候,最大等待時間
logAbandoned 表示被丟棄的數據庫鏈接是否作記錄,以便跟蹤
username 表示數據庫用戶名
password 表示數據庫用戶的密碼
driverClassName 表示JDBC DRIVER
url 表示數據庫URL地址
注意,這裏你配置的name值要和程序中使用的是同樣的,好比按照這個例子,程序就應該是這樣的
String gENV = "java:comp/env/"; Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx .lookup(gENV+"jdbc/mysql"); Connection conn = ds.getConnection(); String gENV = "java:comp/env/"; Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(gENV+"jdbc/db2"); Connection conn = ds.getConnection();
Server.xml方式
Tomcat-6.0.26\conf\context.xml中的配置:在<Host></Host>中添加以下配置 <Context path="/sljx" reloadable="true" docBase="sljx" crossContext="true" debug="0"> <Resource name="jdbc/oracle" type="javax.sql.DataSource" auth="Container" username="sljx" password="sljx" driverClassName="oracle.jdbc.driver.OracleDriver" maxIdle="3000" maxWait="5000" url="jdbc:oracle:thin:@localhost:1521:jadetrus" autoReconnect="true" maxActive="1000"/> </Context>
javax.naming:命名操做;
javax.naming.directory:目錄操做;
javax.naming.event:在命名目錄服務器中請求事件通知;
javax.naming.ldap:提供LDAP支持;
javax.naming.spi:容許動態插入不一樣實現。
void bind(String sName,Object object);――綁定:把名稱同對象關聯的過程
void rebind(String sName,Object object);――從新綁定:用來把對象同一個已經存在的名稱從新綁定
void unbind(String sName);――釋放:用來把對象從目錄中釋放出來
void lookup(String sName,Object object);――查找:返回目錄總的一個對象
void rename(String sOldName,String sNewName);――重命名:用來修改對象名稱綁定的名稱
- 名字(Names),在名字系統中實際對象的代號,如文件名,域名等,它會被用來查找關聯的對象。不一樣的系統中會有不一樣的命名規範,如文件系統採用「\」來表示層級,而DNS則使用「.」。
- 綁定(Bindings),名字和實際對象的關聯。
- 引用和地址(References and Addresses),當對象不能直接被存儲在名字系統時,就必須使用引用,經過引用找到實際的對象。在系統中,保存的引用的內容被稱爲地址。引用還有另外一個用處:在名字系統中,缺乏象關係數據庫中外鍵的概念。經過使用引用,能夠做爲外鍵的一個取代辦法。
- 上下文(Context),它是一個名字-對象集合,提供了與名字系統交互的主要操做,如查找、綁定、去綁定。子上下文(subcontext)與它的關係相似文件系統中目錄和子目錄的關係,子上下文被包含在一個上下文中,經過父上下文中的一個名字與子上下文關聯。
- 名字系統和名字空間(Naming Systems and Namespaces),名字系統是相同類型的上下文的集合,它提供名字服務;名字空間,是名字系統中的名字集合,如文件系統的文件名和目錄。
Directory service 目錄服務是名字服務的擴展,它除了關聯名字和對象,還容許對象包含屬性。目錄系統一般以層次結構組織數據。在目錄服務中的主要概念:
- 屬性(Attributes),它屬於目錄對象,它是(名字,值)對,屬性能夠有多個值。
- 目錄和目錄服務(Directories and Directory Services),目錄是目錄對象的集合;目錄服務則提供與目錄相關的服務,建立、刪除和修改存放在目錄中的對象的屬性。
- 查找和查找過濾器(Searches and Search Filters),獲取目錄對象的操做就是查找;過濾器是相似查找條件的對象。
在使用JNDI以前,須要先獲取JNDI的提供者,並在系統註冊它。與JNDI相關的系統屬性在javax.naming.Context中定義,經常使用的屬性:
- java.naming.factory.initial,服務提供者用來建立InitialContext的類名。
- java.naming.provider.url,用來配置InitialContext的初始url
- java.naming.factory.object,用來建立name-to-object映射的類,用於NameClassPair和References。
- java.naming.factory.state,用來建立jndi state的類
對於目錄服務,因爲通常須要安全設置,還一般使用:
- java.naming.security.authentication,安全類型,三個值:none,simple或strong。
- java.naming.security.principal,認證信息。
- java.naming.security.credentials,證書信息。
- java.naming.security.protocol,安全協議名。
使用System.setProperty註冊,若是程序不顯示說明,那麼java會在classpath內查找jdni.properties文件來完成註冊。jdni.properties例子:
java.naming.factory.initial=com.codeline.db.MockInitialContextFactory
參考:
[1]命名空間及目錄的概念理解:https://docs.oracle.com/javase/tutorial/jndi/concepts/index.html 推薦看看
[2]JNDI概述:https://docs.oracle.com/javase/tutorial/jndi/overview/index.html 推薦看看
[3]JNDI應用配置:https://docs.oracle.com/javase/tutorial/jndi/software/index.html 推薦看看
[4]JNDI幫助主頁:https://docs.oracle.com/javase/tutorial/jndi/index.html
[5]JNDI教程:https://docs.oracle.com/javase/jndi/tutorial/
[6]通俗易懂全面的JNDI介紹:http://blog.csdn.net/kingmax54212008/article/details/52229642