開發訪問 MySQL 的應用,傳統寫法在代碼中硬編碼:驅動類名、JDBC URL、用戶名、密碼。小項目可行,但隨系統演進,問題爆發:
本質:應用代碼與基礎設施細節緊耦合。開發者被迫關心「後台是什麼庫、驅動是什麼、URL 格式、賬號密碼、連接池參數」——這些本不屬於業務邏輯關注點。
容器負責配置與管理資源,應用僅通過邏輯名稱引用。
java:comp/env/jdbc/MySQLDS)Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://MyDBServer:3306/mydb?user=qingfeng&password=mingyue");
// 業務操作...
} finally {
if (conn != null) conn.close();
}
複製 docs/examples/jca/mysql-ds.xml 到 server/default/deploy,修改:
<datasources>
<local-tx-datasource>
<jndi-name>MySQLDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/lw</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>rootpassword</password>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<metadata><type-mapping>MySQL</type-mapping></metadata>
</local-tx-datasource>
</datasources>
Connection conn = null;
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/MySQLDS"); // 僅邏輯名
conn = ds.getConnection();
// 業務操作...
} finally {
if (conn != null) conn.close();
}
| 維度 | 傳統 JDBC 硬編碼 | JNDI + 容器管理 |
|---|---|---|
| 代碼耦合度 | 高(含驅動、URL、憑證、池參數) | 低(僅邏輯 JNDI 名) |
| 環境遷移 | 修改代碼、重編譯、重打包、重部署 | 僅修改容器配置文件,代碼不動 |
| 數據庫切換 | 全局搜索替換驅動類、URL 格式 | 替換 -ds.xml 配置,甚至熱部署 |
| 連接池調優 | 代碼修改 | 容器配置調整 |
| 安全性 | 憑證明文在代碼/構建產物中 | 憑證僅在容器配置,可加密、權限隔離 |
| 運維友好度 | 差 | 優(配置與代碼分離,職責清晰) |
java:/jdbc/{BusinessDomain}{DbType}DSDataSourceUtils 統一獲取/釋放連接,處理異常轉換JDBC 解決「如何連接數據庫」,JNDI 解決「如何在代碼中不寫死連接細節」。從硬編碼到 JNDI 查找,是邁向成熟企業級架構的關鍵一步——配置與代碼分離、基礎設施與業務解耦、部署時綁定替代編譯時綁定。這正是 IoC/DI 思想在資源管理領域的具體實踐。