首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat JNDI 數據源配置實戰:context.xml + web.xml 零代碼獲取連接池

     編輯:Java 綜合教學

Tomcat 內置連接池 JNDI 配置全流程:從 context.xml 到 Servlet 註入,實現零代碼依賴數據源

Tomcat 內置高性能連接池,通過 JNDI 將 DataSource 綁定到 java:comp/env 命名上下文,應用代碼零依賴具體池實現,僅面向 javax.sql.DataSource 接口編程。本文詳細演示 context.xml、web.xml、Servlet 註入的完整配置鏈路。

第一步:META-INF/context.xml 定義資源


<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource 
    name="jdbc/mySource"           
    type="javax.sql.DataSource"    -- 標準接口類型
    username="root"
    password="root"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/java?useSSL=false&serverTimezone=UTC"
    maxActive="20"                 -- 最大活躍連接
    maxIdle="10"                   -- 最大閒置連接
    minIdle="5"                    -- 最小閒置連接
    maxWait="3000"                 -- 獲取連接超時(ms)
    validationQuery="SELECT 1"     -- 連接有效性檢查
    testOnBorrow="true"            -- 借用時檢查
    testWhileIdle="true"           -- 閒置時檢查
    timeBetweenEvictionRunsMillis="60000"
  />
</Context>

位置:Web 專案 src/main/webapp/META-INF/context.xml(Maven 標準目錄),打包後自動進入 WEB-INF/classes/META-INF/ 或 WAR 根目錄 META-INF/。

第二步:web.xml 聲明資源引用(可選但推薦)


<resource-ref>
  <res-ref-name>jdbc/mySource</res-ref-name>  
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>            -- 容器管理認證
</resource-ref>

聲明後,IDE 可提示,部署描述符完整性更好。

第三步:Servlet 中通過 JNDI 獲取 DataSource


public class DataSourceServlet extends HttpServlet {
    private DataSource dataSource;

    @Override
    public void init() throws ServletException {
        try {
            // 1. 獲取初始上下文
            Context initCtx = new InitialContext();
            // 2. 查找 java:comp/env 環境上下文
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            // 3. 查找 DataSource (名稱對應 context.xml 的 name 屬性)
            dataSource = (DataSource) envCtx.lookup("jdbc/mySource");
        } catch (NamingException e) {
            throw new ServletException("JNDI 查找 DataSource 失敗", e);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        try (Connection conn = dataSource.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM user")) {
            
            while (rs.next()) {
                System.out.println(rs.getString("username"));
            }
        } catch (SQLException e) {
            throw new ServletException("數據庫操作異常", e);
        }
    }
}

關鍵注意點

問題原因解決
NameNotFoundExceptionJNDI 名稱不匹配核對 context.xml name、web.xml res-ref-name、代碼 lookup 三者一致
ClassNotFoundException: Driver驅動包不在 Tomcat classpath將 mysql-connector-java.jar 放入 $CATALINA_HOME/lib
連接泄漏未關閉 Connection/Statement/ResultSet務必使用 try-with-resources 或 finally 關閉
需在 Servlet init 獲取JNDI 上下文需 Web 容器初始化完成配置 <load-on-startup>1</load-on-startup> 確保啟動時初始化

web.xml 完整 Servlet 配置


<servlet>
  <servlet-name>DataSourceServlet</servlet-name>
  <servlet-class>com.example.DataSourceServlet</servlet-class>
  <load-on-startup>1</load-on-startup>  
</servlet>
<servlet-mapping>
  <servlet-name>DataSourceServlet</servlet-name>
  <url-pattern>/datasource-demo</url-pattern>
</servlet-mapping>

進階:Spring 整合 Tomcat JNDI DataSource


<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mySource" 
    resource-ref="true" proxy-interface="javax.sql.DataSource" />


@Bean
public DataSource dataSource() throws NamingException {
    JndiTemplate jndi = new JndiTemplate();
    return (DataSource) jndi.lookup("java:comp/env/jdbc/mySource");
}

為什麼選擇 Tomcat JNDI DataSource?

  • 配置與代碼分離:DBA 可直接修改 context.xml 調整池參數,無需重新編譯打包
  • 容器管理生命週期:Tomcat 啟動創建、關閉銷毀,應用無需關心
  • 支援集群/熱部署:多應用共享同一池配置,資源隔離靈活
  • 標準化:符合 Java EE resource-ref 規範,可移植至其他容器

掌握 Tomcat JNDI DataSource 配置,是從「寫死連接池代碼」向「企業級部署運維」邁進的關鍵一步。建議在開發環境同步配置,養成「代碼只依賴接口,配置由容器注入」的良好習慣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved