1. 什么是jndi
jndi的作用看起来和datasource查不多,定义一个数据源,比如更换了数据库或需要更改配置信息,我们只需要修改注册信息,代码中引入的是一个key(资源名),只要key不变,因此代码也不需要修改。
传统用法,非jndi:
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver", true, Thread.currentThread().getContextClassLoader());
conn=DriverManager.getConnection("jdbc:mysql://MyDBServer?user=xxx&password=xxx");
......
conn.close();
} catch(Exception e) {
e.printStackTrace();
} finally {
if(conn!=null) {
try {
conn.close();
} catch(SQLException e) {}
}
}
这是传统的做法,也是以前非Java程序员(如Delphi、VB等)常见的做法。这种做法一般在小规模的开发过程中不会产生问题,只要程序员熟悉Java语言、了解JDBC技术和MySQL,可以很快开发出相应的应用程序。
没有JNDI的做法存在的问题:
1、数据库服务器名称MyDBServer 、用户名和口令都可能需要改变,由此引发JDBC URL需要修改;
2、数据库可能改用别的产品,如改用DB2或者Oracle,引发JDBC驱动程序包和类名需要修改;
3、随着实际使用终端的增加,原配置的连接池参数可能需要调整;
4、…
2. jndi配置
在描述JNDI,例如获得数据源时,JNDI地址有两种写法,例如同是 jdbc/testDS 数据源:
-
java:comp/env/jdbc/testDS 带 java:comp前缀
-
jdbc/testDS
这两种写法,配置的方式也不尽相同,第一种方法应该算是一种利于程序移植或迁移的方法,它的实现与“映射”的概念相同,而第二种方法,则是一个硬引用。
java:comp/env 是环境命名上下文(environment naming context(ENC)),是在EJB规范1.1以后引入的,引入这个是为了解决原来JNDI查找所引起的冲突问题,也是为了提高EJB或者J2EE应用的移植性。
在J2EE中的引用常用的有:
- JDBC 数据源引用在java:comp/env/jdbc 子上下文中声明
- JMS 连接工厂在java:comp/env/jms 子上下文中声明
- JavaMail 连接工厂在java:comp/env/mail 子上下文中声明
- URL 连接工厂在 java:comp/env/url子上下文中声明
结论:
- context.lookup(“XXX”)在任何时候都是有效的,只要XXX确实是一个存在的JNDI名。
- context.lookup(“java:comp/env/XXX”)只能用在J2EE环境,如果你自己写一个main函数,想通过context.lookup(“java:comp/env/XXX”)这样的方式来访问JNDI服务,这是不可能的。
java:comp/env/是一个J2EE环境的定义,说白了就是代表当前J2EE应用的环境,比如你自己项目的Web环境或者是EJB环境。那是不是只要是个Web项目,就能用context.lookup(“java:comp/env/XXX”)这种方式访问JNDI服务了呢?也不是!!!
2.1 weblogic例子:
用weblogic10的控制台定义了一个oracle数据源,这个数据源的JNDI名称是:adsl,那么只要正确连接上了weblogic(当然需传递URL,用户名和密码还有weblogic的JNDI工厂对象,这不属于该文的讨论范围)在任何地方都能用context.lookup(“xxx”)得到这个数据源了,但是想通过context.lookup(“java:comp/env/jdbc/adsl”)访问到这个数据源,就不行了。
如果想这样写的话需要做两件事情:
-
1、确保你的调用程序是一个web项目或者EJB(Enterprise JavaBean)项目,并部署到weblogic上。(例子使用web项目)
-
2、在web项目的web.xml里面加上如下配置:
<resource-ref>
<res-ref-name>jdbc/adsl</res-ref-name>
<res-auth>Container</res-auth>
<mapped-name>adsl</mapped-name> <!-- 这个必须和你的全局JNDI数据源名称一样 -->
</resource-ref>
那么你就能在你的web程序里通过context.lookup(“java:comp/env/jdbc/adsl”)访问到这个数据源了。
2.2 其他服务器
如果不是使用weblogic,可参见这篇文章 《关于Jboss/Tomcat/Jetty的JNDI定义》
tomcat的数据源配置可以配置在项目中,也可以配置在全局中,多个项目可以共享。