概述
本文介绍如何从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 }