jndi的一点介绍(转)
2009-04-30 21:34
218 查看
没有对 JDBC
驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。Dolly
需要编写代码来忽略将要访问的特定外部资源,只需要知道其他人会提供使用这些外部资源所需的链接即可。这允许部署人员(任何处在这个角色的人)把数据库连
接分配给 Dolly 的应用程序。Dolly 没有必要参与其中。(从数据库安全性到遵守 Sarbanes-Oxley
法案,她都没有参与进来,她这样做也有充足的业务理由。)
许多开发人员知道:代码和外部资源之间的紧密耦合是潜在的问题,但是在实践中却经常忘记角色的划分。在小型开发工作中(指的是团队规模或部署规
模),即使忽视角色划分也能获得成功。(毕竟,如果应用程序只是个人的应用程序,而且您不准备依靠它,那么把应用程序锁定在特定的
PostgreSQL 实例上也挺好的。)
J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现。JNDI 在 J2EE 中的角色就是“交换机” —— J2EE
组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下,提供 JNDI
供应者的容器可以充当有限的数据存储,这样管理员就可以设置应用程序的执行属性,并让其他应用程序引用这些属性(Java 管理扩展(Java
Management Extensions,JMX)也可以用作这个目的)。JNDI 在 J2EE
应用程序中的主要角色就是提供间接层,这样组件就可以发现所需要的资源,而不用了解这些间接性。
现在我们重新来看一下 Dolly 的情况。在其简单的 Web 应用程序中,她直接从应用程序代码中使用了一个 JDBC 连接。参见清单
1,我们可以看出,Dolly 显式地把 JDBC 驱动程序、数据库 URL 以及她的用户名和口令编码到了 servlet 中:
清单 1. 典型(但是不好)的 JDBC 用法
如果不用这种方式指定配置信息,Dolly(以及她的同伴们)使用 JNDI 来查找 JDBC
清单 2. 使用 JNDI 得到数据源
为了能够得到 JDBC 连接,首先要执行一些小的部署配置,这样我们才可以在本地组件的 JNDI 下文中查找
配置 JNDI 引用
为了让 JNDI 解析
清单 3. resource-ref 入口
这只定义了到外部资源的本地引用,还没有创建引用指向的实际资源。(在 Java 语言中,类似的情况可能是:
部署人员的工作就是创建
指向它,在我们的 Java 语言示例中就是这样)。每个容器都有自己设置数据源的机制。例如,在 JBoss 中,是利用服务来定义数据源(请参阅
$JBOSS/server/default/deploy/hsqldb-ds.xml,把它作为示例),它指定自己是
清单 4. 用特定于供应商的部署描述符将资源绑定到 JDI 名称
这表明应该将本地资源引用名称(
驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。Dolly
需要编写代码来忽略将要访问的特定外部资源,只需要知道其他人会提供使用这些外部资源所需的链接即可。这允许部署人员(任何处在这个角色的人)把数据库连
接分配给 Dolly 的应用程序。Dolly 没有必要参与其中。(从数据库安全性到遵守 Sarbanes-Oxley
法案,她都没有参与进来,她这样做也有充足的业务理由。)
许多开发人员知道:代码和外部资源之间的紧密耦合是潜在的问题,但是在实践中却经常忘记角色的划分。在小型开发工作中(指的是团队规模或部署规
模),即使忽视角色划分也能获得成功。(毕竟,如果应用程序只是个人的应用程序,而且您不准备依靠它,那么把应用程序锁定在特定的
PostgreSQL 实例上也挺好的。)
J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现。JNDI 在 J2EE 中的角色就是“交换机” —— J2EE
组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下,提供 JNDI
供应者的容器可以充当有限的数据存储,这样管理员就可以设置应用程序的执行属性,并让其他应用程序引用这些属性(Java 管理扩展(Java
Management Extensions,JMX)也可以用作这个目的)。JNDI 在 J2EE
应用程序中的主要角色就是提供间接层,这样组件就可以发现所需要的资源,而不用了解这些间接性。
现在我们重新来看一下 Dolly 的情况。在其简单的 Web 应用程序中,她直接从应用程序代码中使用了一个 JDBC 连接。参见清单
1,我们可以看出,Dolly 显式地把 JDBC 驱动程序、数据库 URL 以及她的用户名和口令编码到了 servlet 中:
清单 1. 典型(但是不好)的 JDBC 用法
Connection conn=null; try { Class.forName("com.mysql.jdbc.Driver", true, Thread.currentThread().getContextClassLoader()); conn=DriverManager.getConnection("jdbc:mysql://dbserver?user=dolly&password=dagger"); /* use the connection here */ c.close(); } catch(Exception e) { e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch(SQLException e) {} } } |
DataSource会更好一些,如清单 2 所示:
清单 2. 使用 JNDI 得到数据源
Connection conn=null; try { Context ctx=new InitialContext(); Object datasourceRef=ctx.lookup("java:comp/env/jdbc/mydatasource"); DataSource ds=(Datasource)datasourceRef; Connection c=ds.getConnection(); /* use the connection */ c.close(); } catch(Exception e) { e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch(SQLException e) { } } } |
DataSource。这可能有点烦琐,但是很容易学。不幸的是,这意味着即使是为了测试组件,开发人员也必须涉足部署人员的领地,并且还要准备配置应用服务器。
配置 JNDI 引用
为了让 JNDI 解析
java:comp/env/jdbc/mydatasource引用,部署人员必须把
<resource-ref>标签插入 web.xml 文件(Web 应用程序的部署描述符)。
<resource-ref>标签的意思就是“这个组件依赖于外部资源”。清单 3 显示了一个示例:
清单 3. resource-ref 入口
<resource-ref> <description>Dollys DataSource</description> <res-ref-name>jdbc/mydatasource</res-ref-name> <res-ref-type>javax.sql.DataSource</res-ref-type> <res-auth>Container</res-auth> </resource-ref> |
<resource-ref>入口告诉 servlet 容器,部署人员要在 组件命名上下文(component naming context) 中设置一个叫做
jdbc/mydatasource的资源。组件命名上下文由前缀
java:comp/env/表示,所以完全限定的本地资源名称是:
java:comp/env/jdbc/mydatasource.
这只定义了到外部资源的本地引用,还没有创建引用指向的实际资源。(在 Java 语言中,类似的情况可能是:
<resource-ref>声明了一个引用,比如
Object foo,但是没有把
foo设置成实际引用任何
Object。)
部署人员的工作就是创建
DataSource(或者是创建一个
Object对象,让
foo
指向它,在我们的 Java 语言示例中就是这样)。每个容器都有自己设置数据源的机制。例如,在 JBoss 中,是利用服务来定义数据源(请参阅
$JBOSS/server/default/deploy/hsqldb-ds.xml,把它作为示例),它指定自己是
DataSource的全局 JNDI 名称(默认情况下是
DefaultDS)。在创建资源之后,第三步仍然很关键:把资源连接或者绑定到应用程序组件使用的本地名称。在使用 Web 应用程序的情况下,是使用特定于供应商的部署描述符扩展来指定这个绑定,清单 4 中显示了一个这样的例子。(JBoss 用称为
jboss-Web.xml的文件作为特定于供应商的 Web 应用程序部署描述符。)
清单 4. 用特定于供应商的部署描述符将资源绑定到 JDI 名称
<resource-ref> <res-ref-name>jdbc/mydatasource</res-ref-name> <jndi-name>java:DefaultDS</jndi-name> </resource-ref> |
jdbc/mydatasource)映射到名为
java:DefaultDS的全局资源。如果全局资源名称出于某种原因发生了变化,而应用程序的代码无需变化,那么只需修改这个映射即可。在这里,有两个级别的间接寻址:一个定义并命名资源(
java:DefaultDS),另一个把特定于本地组件的名称(
jdbc/mydatasource)绑定到命名的资源。(实际上,当您在 EAR 级别上映射资源时,可能还存在第三级别的间接寻址。)
相关文章推荐
- EBS中FND_REQUEST.SUBMIT_REQUEST的一点介绍
- 关于Sqlite数据库Update语句的一点介绍
- JNDI介绍
- 简单JSF举例来介绍JSF应用及此MVC框架的一点好处
- JNDI介绍
- JNDI介绍(详解,什么是JNDI)
- JNDI技术、JDBC框架、几种元数据介绍
- Python 提交表单数的一点简单介绍
- JNDI精要介绍
- JNDI介绍(详解,什么是JNDI)
- 关于JNDI的一些介绍,很好。
- C++学习 std::tr1::shared_ptr使用的一点体会tr1库介绍
- JNDI技术、JDBC框架、几种元数据介绍
- JNDI介绍(详解,什么是JNDI)
- JNDI介绍
- JNDI技术、JDBC框架、几种元数据介绍
- JNDI的详细介绍
- JNDI介绍之 Naming Package
- 关于Sqlite数据库Update语句的一点介绍 .