JNDI在Spring和tomcat下的使用


1. 是什么

JNDI是 Java 命名與目錄接口(Java Naming and Directory Interface),在J2EE規范中是重要的規范之一。JNDI 在 J2EE 中的角色就是“交換機” —— J2EE 組件在運行時間接地查找其他組件、資源或服務的通用機制。在多數情況下,提供 JNDI 供應者的容器可以充當有限的數據存儲,這樣管理員就可以設置應用程序的執行屬性,並讓其他應用程序引用這些屬性(Java 管理擴展(Java Management Extensions,JMX)也可以用作這個目的)。JNDI 在 J2EE 應用程序中的主要角色就是提供間接層,這樣組件就可以發現所需要的資源,而不用了解這些間接性。

2. 為何用

程序員可以不用關心“具體的數據庫后台是什么?JDBC驅動程序是什么?訪問數據庫的用戶名和口令是什么?”等等這些問題,而是把這些問題交給J2EE容器來配置和管理,程序員只需要對這些配置和管理進行引用即可。

3. 怎么用

3.1 整體思路

  1. 在在J2EE容器如Tomcat中配置一個數據源,給這個數據源設置一個名稱;
  2. 在項目程序中,通過數據源名稱引用這個數據源從而訪問后台數據庫

3.2 示例

下面在Tomcat6.0+spring+springMVC+mybatis項目中演示用法。

Tomcat
  • 方法一:非全局的Resource,只更改context.xml

在context.xml的根節點Context里加入Resource配置

  <Resource name="jdbc/mmcDB"       //指定的jndi名稱,會用於spring數據源bean的配置和ResourceLink的配置
                 auth="Container"//認證方式,一般默認這個
                 type="javax.sql.DataSource"   //數據源床型,使用標准的javax.sql.DataSource
                 driverClassName="com.mysql.jdbc.Driver"    //JDBC驅動器 
                 url="jdbc:mysql://localhost:3306/test" //數據庫URL地址             
                 username="test"     //數據庫用戶名
                 password="test"   //數據庫密碼
                 maxIdle="40"   //最大的空閑連接數
                 maxWait="4000" //當池的數據庫連接已經被占用的時候,最大等待時間
                 maxActive="250" //連接池當中最大的數據庫連接
                 removeAbandoned="true" 
                 removeAbandonedTimeout="180"
                 logAbandoned="true" //被丟棄的數據庫連接是否做記錄,以便跟蹤
                 factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" />
  • factory:該Resource 配置使用的是哪個數據源配置類,這里使用的是tomcat自帶的標准數據源Resource配置類,這個類也可以自己寫,實現javax.naming.spi.ObjectFactory 接口即可。

    如果使用其他的數據池,如阿里巴巴的druid,要滿足兩個條件:

    1. 其實現了javax.naming.spi.ObjectFactory,druid的com.alibaba.druid.pool.DruidDataSourceFactory就實現了
    2. 需把jar及其依賴的jar包 ,都放在tomcat的lib下,光放在工程的WEB-INF/lib下是不夠的。阿里巴巴的druid依賴log4j,所以后者的jar也要復制進去
  • driverClassName的其他寫法:

    oracle:oracle.jdbc.driver.OracleDriver

    db2:com.ibm.db2.jcc.DB2Driver

    SQLServer:com.microsoft.sqlserver.jdbc.SQLServerDriver

  • url的其他寫法示例:

    oracle:jdbc:oracle:thin:@192.168.1.249:1521:XE

    db2:jdbc:db2://18.1.99.7:55555/esdb:currentSchema=EMPSAL

  • 這種配法可寫多個resource給不同的項目使用

  • 方法二:全局的 Resource,更改server.xml和context.xml

    • server.xml:在server.xml的GlobalNamingResources節點里加入Resource,再在Context節點里加入ResourceLink的配置。全局的resource只是為了重用,方便所有該tomcat下的web工程的數據源管理,但如果你的tomcat不會同時加載多個web工程,也就是說一個tomcat只加載一個web工程時,是沒有必要配置全局的resource的。
    把上面的context.xml的Resource標簽加內容直接拷貝到server.xml的GlobalNamingResources標簽里就行了
    
    • 接下來有四種方式引用這個全局的Resource

      方法2沒弄出來,方法1,3,4是可以的,事實上3和4是同一種方法,只要在建項目時在項目的webapps/mmc/META-INF/下寫好context.xml,這兩個方法所要求的context.xml都會在啟動tomcat后自動生成(tomcat7.0沒有自動生成,不過這樣寫過后相當於用來方法4,一樣可以成功啟動)

      1. 直接在conf/context.xml里引用
      <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>      
      
      1. 這個方法我用tomcat6.0和7.0都失敗了,報找不到mmcDB,暫時用不到就不深究了,列出了給大家參考吧 ......conf/server.xml里繼續配置,該方法可以指定把哪些source綁定到哪個web工程下。
      <!-- 在host標簽內新增,第一行為加載的工程配置,第二行是該工程需要的ResourceLink配置 -->
      <context docBase="mmc" path="" reloadable="false"> 
           <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>
      </context>
      
      1. 安裝目錄下的conf/Catalina/localhost/下建立一個xml文件,文件名是<yourAppName>.xml。比如工程名為mmc,則該xml名為mmc.xml。
      <?xml version="1.0" encoding="UTF-8"?>
      <Context>   
           <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>       
      </context>
      
      1. tomcat安裝目錄下的\webapps\test\META-INF\context.xml的Context節點中增加:
      <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>
      
Spring
  • 方法一:
<bean id="testDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName">
          <value>java:comp/env/jdbc/mmcDB</value>
     </property>
</bean>
或者:
<bean id="testDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName">
          <value>jdbc/mmcDB</value>
     </property>
     <property name="resourceRef">
          <value>true</value>
     </property>
</bean>
  • 方式二:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/mmcDB" />

3.3 細節解釋

  • Tomcat中在server.xml下配置你必需重啟服務器才能生效,而context.xml配置保存后tomcat會自動加載無需重啟

  • JNDI地址寫法:AB兩種地址的用法可點擊參考資料的第一條鏈接查看
    在描述JNDI,例如獲得數據源時,JNDI地址 有兩種寫法,例如同是 jdbc/testDS 數據源:
    A: java:comp/env/jdbc/testDS
    B: jdbc/testDS
    這兩種寫法,配置的方式也不盡相同,用A就行了別糾結,網上查了一堆資料都說的亂七八糟。
    java:comp/env 是環境命名上下文(environment naming context(ENC)),是在EJB規范1.1以后引入的,引入這個是為了解決原來JNDI查找所引起的沖突問題,也是為了提高EJB或者J2EE應用的移植性。
    在J2EE中的引用常用的有:
    JDBC 數據源引用在java:comp/env/jdbc 子上下文中聲明
    JMS 連接工廠在java:comp/env/jms 子上下文中聲明
    JavaMail 連接工廠在java:comp/env/mail 子上下文中聲明
    URL 連接工廠在 java:comp/env/url子上下文中聲明

4. 參考資料

  1. http://stackoverflow.com/questions/4099095/what-does-javacomp-env-do
  2. http://blog.csdn.net/cyong888/article/details/7361466


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM