概述
本文介紹如何從javax.naming.InitialContext中獲取web容器配置的數據源。
在web開發中,常見的獲取數據源的方式是把數據源定義為spring的bean,其他類通過spring注入來獲取數據源。可能遇到的問題如下:
- 需要獲取數據源的類不是spring bean,無法接收注入。
- 系統中沒有使用spring框架。
解決問題的方法可能有很多,這里提供基於InitialContext的解決方案。
解決方案
javax.naming.InitialContext ic = new javax.naming.InitialContext(); javax.sql.DataSource ds = (javax.sql.DataSource) ic.lookup(jndiName);
補充說明:
- 個別web容器配置的JNDI需要加固定前綴才是可查找JNDI,如Tomcat,需要加前綴"java:comp/env/"。
- 以上展示的僅僅只是最直接的做法,考慮到InitialContext是一個重量級的類,應該進行一定的優化來減少其創建次數。
以下提供一個項目中使用的工具類:

1 package cn.com.hnisi.baseservices.db; 2 import javax.naming.InitialContext; 3 import javax.naming.NamingException; 4 import javax.sql.DataSource; 5 import cn.com.hnisi.baseservices.config.Config; 6 /** 7 * SINOBEST 數據源工廠,用於獲取DataSource.<br> 8 * 使用JNDI查找上下文中的DataSource.<br> 9 * @author lijinlong 10 * 11 */ 12 public class DataSourceFactory { 13 private static DataSourceFactory instance; 14 private static InitialContext context; 15 /** 默認的數據源的jndi名稱屬性的key */ 16 private static final String DEFAULT_DATASOURCE_PROP_KEY = "DB.DATASOURCE"; 17 18 private DataSourceFactory() { 19 super(); 20 } 21 22 /** 23 * 單例模式獲取工廠實例.<br> 24 * @return 25 */ 26 public static final synchronized DataSourceFactory newInstance() { 27 if (instance == null) 28 instance = new DataSourceFactory(); 29 return instance; 30 } 31 32 /** 33 * 獲取默認的DataSource.<br> 34 * 根據config/config.properties中DB.DATASOURCE屬性值查找.<br> 35 * @return 36 */ 37 public DataSource getDefaultDataSource() { 38 String jndiName = Config.getInstance().getValue(DEFAULT_DATASOURCE_PROP_KEY); 39 DataSource ds = getDataSource(jndiName); 40 return ds; 41 } 42 43 /** 44 * 根據JNDI名稱,獲取上下文中的DataSource.<br> 45 * @param jndiName 46 * @return 47 */ 48 public synchronized DataSource getDataSource(String jndiName) { 49 DataSource ds = null; 50 try { 51 if (context == null) 52 context = new InitialContext(); 53 ds = (DataSource)context.lookup(jndiName); 54 } catch (NamingException e) { 55 e.printStackTrace(); 56 } 57 return ds; 58 } 59 }