JNDI的學習與使用

JNDI(Java Naming and Directory Interface,Java命名和目錄接口)是一組在Java應用中訪問命名和目錄服務的API。命名服務將名稱和對象聯繫起來,使得咱們能夠用名稱訪問對象。這是比較專業的解釋。html

咱們通常是在數據源這塊使用JNDI,有些服務器(例如Tomcat)中自帶數據庫鏈接池,咱們能夠經過JNDI服務去這個鏈接池中找到對應的數據源Connection。因此個人一個比較狹隘的理解是:服務器在初始化Connection以後,就會放在默認的鏈接池中,由於可能會有多個數據源,因此就須要有一個名稱去對應,而JNDI正是去作這項工做。java

須要理解的是JNDI與JDBC相似,都是制定了一套標準,而不是具體的實現。sql

JNDI配置(局部配置)

局部配置只針對當前項目有效。在項目的META-INF 下創建context.xml (這是固定名稱) 。在這個XML中配置數據庫鏈接的四大參數,鏈接池的配置(不指定具體配置也會有默認值),JNDI的名稱等屬性數據庫

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
    - name:表示之後要查找的名稱。經過此名稱能夠找到DataSource,此名稱任意更換,可是程序中最終要查找的就是此名稱,爲了避免與其餘的名稱混淆,因此使用jdbc/oracle,如今配置的是一個jdbc的關於oracle的命名服務。
    - auth:由容器進行受權及管理,指的用戶名和密碼是否能夠在容器上生效
    - type:此名稱所表明的類型,如今爲javax.sql.DataSource
    - maxActive:表示一個數據庫在此服務器上所能打開的最大鏈接數 Tomcat8.0及以上版本使用maxTotal
    - maxIdle:表示一個數據庫在此服務器上維持的最大空閒鏈接
    - maxWait:最大等待時間。10000毫秒 設置爲-1表示無限等待 Tomcat8.0及以上版本使用DBCP2 部署這些服務器須要使用maxWaitMillis
    - username:數據庫鏈接的用戶名
    - password:數據庫鏈接的密碼
    - driverClassName:數據庫鏈接的驅動程序
    - url:數據庫鏈接的地址
    - initialSize:初始化鏈接數
-->
    <Resource name="jndi/oracle"
              auth="Container"
              type="javax.sql.DataSource"
              driverClassName="oracle.jdbc.driver.OracleDriver"
              url="jdbc:oracle:thin:@localhost:1521:Orcl"
              username="scott"
              password="tiger"
              maxActive="20"
              maxIdle="5"
              maxWait="10000"
              initialSize="10"/>
</Context>

若是有多個數據源的需求,配置多個Resource 標籤便可,根據name區分。apache

在未使用其餘數據庫鏈接池的狀況下,會默認使用Servlet容器自帶的數據源(Tomcat自帶的是DBCP數據源,畢竟是Apache一家的產品,能夠在Tomcat-安裝目錄/lib 下找到這個jar),可是須要注意的是Tomcat版本之間有些許差別:Tomcat7使用的是DBCP,Tomcat8及以上版本使用的是DBCP2,這兩個DBCP的一些鏈接池配置項名稱有些許不一樣,須要使用對應的名稱,不然該項的自定義配置不會生效,而是使用默認配置。DBCP所有的配置能夠看這裏: DBCP官方文檔tomcat

測試JNDI是否生效

這裏使用Servlet只是爲了方便測試(由於JDNI須要依賴Servlet容器,而且容器須要開啓),最主要的操做就是經過JNDI得到Connection服務器

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class JNDITest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Context ctx;
        DataSource ds = null;
        try {
            ctx = new InitialContext();
            //java:comp/env/ 是固定寫法 後面的名字是在context.xml中配置的
            ds = (DataSource) ctx.lookup("java:comp/env/jndi/oracle");
            Connection conn = null;
            try {
                conn = ds.getConnection();
                System.out.println(conn.getClass());
                System.out.println(conn.isClosed());
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
 <servlet>
    <servlet-name>JNDITest</servlet-name>
    <servlet-class>JNDITest</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>JNDITest</servlet-name>
    <url-pattern>/JNDITest</url-pattern>
</servlet-mapping>

Servlet的配置沒什麼可說的,主要在乎的使用 javax.naming.Context 並根據JNDI名lookup一個DataSource,還有就是注意這個JNDI的名稱寫法,是有要求的oracle

JNDI配置(全局配置)

全局配置是配置在Tomcat的配置上的,全部部署在這臺Tocmat上的項目,在未使用其餘數據庫鏈接池的狀況下,會默認使用這個配置。在tomcat-安裝目錄\conf\server.xml 文件中有一個GlobalNamingResources 標籤,在它下面配置 Resource 標籤, 具體的配置項和在context.xml 中配置相似,這種全局配置應該使用的並不過吧...app

相關文章
相關標籤/搜索