JNDI即Java命名和目錄接口,英文全稱為Java Naming and Directory Interface,從字面上似乎十分晦澀,下面從理論和實際項目應用方面來闡述。
1、命名:在我們實際生活或工作中,命名類似如你的身份證號和工號可以"理解"成一種命名服務,即一個值到另一個值的映射,從身份證或工號就可以得知你人本身。
2、目錄服務:從計算機角度理解為在互聯網上有着各種各樣的資源和主機,但是這些內容都是散落在互聯網中,為了訪問這些散落的資源並獲得相應的服務,就需要用到目錄服務。
在實際項目開發過程中,對於數據源配置方面,JNDI的應用就是一個很好的例子。
對於一個簡單的系統,我們一般會將數據庫的連接url、用戶名、密碼、數據源(c3p0,dbcp等)配置在本系統中,對於SSH項目,通常會這些寫在配置文件(properties、xml等)中,在系統初始化的時候,進行讀取加載。
存在的問題:
1、數據庫服務器名稱MySQL、用戶名和密碼都可能需要改變,由此引發JDBC URL需要修改;
2、數據庫可能改用別的產品,如改用DB2或者Oracle,引發JDBC驅動程序包和類名需要修改;
3、隨着實際使用終端的增加,原配置的連接池參數可能需要調整;
即耦合性太高。
使用JNDI的案例:
在在J2EE容器中配置JNDI參數,定義一個數據源,也就是JDBC引用參數,給這個數據源設置一個名稱,然后在程序中,通過數據源名稱引用數據源從而訪問后台數據庫。
如果項目中使用到spring,可以定義一個spring-res.xml,用於定義使用的jndi名稱。
如:
<!-- JNDI數據源 -->
<jee:jndi-lookup id="dataSource" jndi-name="jndi/Java"
proxy-interface="javax.sql.DataSource" lookup-on-startup="false" />
即配置數據源名稱為jndi/Java,
如果使用Tomcat作為web容器,則在context.xml中配置:
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="20"
maxIdel="10" maxWait="1000" name="jndi/shds" type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/java?user=xxx&password=123#pwd&useUnicode=true&characterEncoding=utf8&autoReconnect=true&generateSimpleParameterMetadata=true&" />
如果使用JBOSS作為web容器,則在mysql-ds.xml修改
在程序中引用數據源:
Context ctx=new InitialContext();
Object datasourceRef=ctx.lookup("jndi/Java"); //引用數據源,實際項目中,可以獲取spring-res.xml配置文件中jndi-name來獲取實際數據源名稱。
DataSource ds=(Datasource)datasourceRef;
conn=ds.getConnection();
在系統部署后,如果數據源參數發生改變,只要jndi名稱不改,那么我們只要在一個地方修改配置即可,不需要修改源代碼,從而是程序員真正關心代碼邏輯的實現,
也達到解耦的目的。
JNDI的擴展:JNDI在滿足了數據源配置的要求的基礎上,還進一步擴充了作用:所有與系統外部的資源的引用,都可以通過JNDI定義和引用。