JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,不少专家认为,没有透彻理解JNDI的意义和作用,就没有真正掌握J2EE特别是EJB的知识。

那么,JNDI到底起什么作用?



要了解JNDI的作用,我们可以从“如果不用JNDI我们怎样做?用了JNDI后我们又将怎样做?”这个问题来探讨。

1. 没有JNDI的做法

程序员开发时,知道要开发访问MySQL数据库的应用,于是将一个对 MySQL JDBC 驱动程序类的引用进行了编码,并通过使用适当的 JDBC URL 连接到数据库。

就像以下代码这样:

Connection conn=null;
try {
   Class.forName("com.mysql.jdbc.Driver",
                 true, Thread.currentThread().getContextClassLoader());
   conn=DriverManager.getConnection("jdbc:mysql://MyDBServer?user=qingfeng&password=mingyue");
   /* 使用conn并进行SQL操作 */
   
   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、......



解决办法:

程序员应该不需要关心“具体的数据库后台是什么?JDBC驱动程序是什么?JDBC URL格式是什么?访问数据库的用户名和口令是什么?”等等这些问题,程序员编写的程序应该没有对 JDBC 驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。而是把这些问题交给J2EE容器来配置和管理,程序员只需要对这些配置和管理进行引用即可。



由此,就有了JNDI。

2. 用了JNDI之后的做法

首先,在在J2EE容器中配置JNDI参数,定义一个数据源,也就是JDBC引用参数,给这个数据源设置一个名称;然后,在程序中,通过数据源名称引用数据源从而访问后台数据库。

具体操作如下(以JBoss为例):

1、配置数据源

在JBoss的 D:"jboss420GA"docs"examples"jca 文件夹下面,有很多不同数据库引用的数据源定义模板。将其中的 mysql-ds.xml 文件Copy到你使用的服务器下,如 D:"jboss420GA"server"default"deploy。

修改 mysql-ds.xml 文件的内容,使之能通过JDBC正确访问你的MySQL数据库,如下:

<?xml version="1.0" encoding="UTF-8"?>

<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>

这里,定义了一个名为MySqlDS的数据源,其参数包括JDBC的URL,驱动类名,用户名及密码等。

Tomcat中的配置方法:

<context path="/tudu" docbase="/home/web/Tudu &gt;&lt;br /&gt;&lt;Resource name=" auth="Container" type="javax.sql.DataSource">

<resourceparams name="jdbc/tudu">

<parameter>

<name>username</name>

<value>system</value>

</parameter>

<parameter>

<name>password</name>

<value>manager</value>

</parameter>

<parameter>

<name>driverClassName</name>

<value>com.mysql.jdbc.Driver</value>

</parameter>

<parameter>

<name>url</name>

<value>jdbc:mysql://localhost:3306/tudu</value>

</parameter>

</resourceparams>

</context>

2、在程序中引用数据源:

Connection conn=null;

try {

Context ctx=new InitialContext();

Object datasourceRef=ctx.lookup("java:MySqlDS"); //引用数据源

DataSource ds=(Datasource)datasourceRef;

conn=ds.getConnection();

/* 使用conn进行数据库SQL操作 */

c.close();

}

catch(Exception e) {

e.printStackTrace();

}

finally {

if(conn!=null) {

try {

conn.close();

} catch(SQLException e) { }

}

}

直接使用JDBC或者通过JNDI引用数据源的编程代码量相差无几,但是现在的程序可以不用关心具体JDBC参数了。

在系统部署后,如果数据库的相关参数变更,只需要重新配置 mysql-ds.xml 修改其中的JDBC参数,只要保证数据源的名称不变,那么程序源代码就无需修改。



由此可见,JNDI避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。



JNDI的扩展:

JNDI在满足了数据源配置的要求的基础上,还进一步扩充了作用:所有与系统外部的资源的引用,都可以通过JNDI定义和引用。



所以,在J2EE规范中,J2EE 中的资源并不局限于 JDBC 数据源。引用的类型有很多,其中包括资源引用(已经讨论过)、环境实体和 EJB 引用。特别是 EJB 引用,它暴露了 JNDI 在 J2EE 中的另外一项关键角色:查找其他应用程序组件。



EJB 的 JNDI 引用非常类似于 JDBC 资源的引用。在服务趋于转换的环境中,这是一种很有效的方法。可以对应用程序架构中所得到的所有组件进行这类配置管理,从 EJB 组件到 JMS 队列和主题,再到简单配置字符串或其他对象,这可以降低随时间的推移服务变更所产生的维护成本,同时还可以简化部署,减少集成工作。外部资源”。





总结:

J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现。JNDI 在 J2EE 中的角色就是“交换机” —— J2EE 组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下,提供 JNDI 供应者的容器可以充当有限的数据存储,这样管理员就可以设置应用程序的执行属性,并让其他应用程序引用这些属性(Java 管理扩展(Java Management Extensions,JMX)也可以用作这个目的)。JNDI 在 J2EE 应用程序中的主要角色就是提供间接层,这样组件就可以发现所需要的资源,而不用了解这些间接性。



在 J2EE 中,JNDI 是把 J2EE 应用程序合在一起的粘合剂,JNDI 提供的间接寻址允许跨企业交付可伸缩的、功能强大且很灵活的应用程序。这是 J2EE 的承诺,而且经过一些计划和预先考虑,这个承诺是完全可以实现的。

Java基础学习总结(26)——JNDI入门简介的更多相关文章

  1. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  2. Java基础-SSM之Spring MVC入门篇

    Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...

  3. JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API

    森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397  文章- 0  评论- 78  JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...

  4. Java基础-SSM之mybatis快速入门篇

    Java基础-SSM之mybatis快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实你可能会问什么是SSM,简单的说就是spring mvc + Spring + m ...

  5. Java基础-StringBuffer类与StringBuilder类简介

    Java基础-StringBuffer类与StringBuilder类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringBuffer类 在学习过String类之后 ...

  6. [转帖]java基础学习总结——多态(动态绑定)

    https://www.cnblogs.com/xdp-gacl/p/3644035.html 多态的概念 java基础学习总结——多态(动态绑定) 一.面向对象最核心的机制——动态绑定,也叫多态

  7. java基础学习笔记五(抽象类)

    java基础学习总结——抽象类 抽象类介绍

  8. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

  9. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  10. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

随机推荐

  1. PIC kit3问题

    1.通过pic kit3烧录pic16F1938的时候,pic kit3自动更新了firmware,但是仍然烧录不了pic16F1938,然后再次用pic kit3烧录pic18F45k80时,一直显 ...

  2. How Javascript works (Javascript工作原理) (五) 深入理解 WebSockets 和带有 SSE 机制的HTTP/2 以及正确的使用姿势

    个人总结: 1.长连接机制——分清Websocket,http2,SSE: 1)HTTP/2 引进了 Server Push 技术用来让服务器主动向客户端缓存发送数据.然而,它并不允许直接向客户端程序 ...

  3. 《Craking the Coding interview》python实现---02

    ###题目:翻转一个字符串###思路:从字符串的最后一位开始,依次取###实现:伪代码.函数.类实现#伪代码: #01string=sNew_s=""for i in range( ...

  4. Java基础学习总结(43)——Java8 Lambda揭秘

    再了解了Java 8 Lambda的一些基本概念和应用后, 我们会有这样的一个问题: Lambda表达式被编译成了什么?. 这是一个有趣的问题,涉及到JDK的具体的实现. 本文将介绍OpenJDK对L ...

  5. 洛谷 P3147 [USACO16OPEN]262144

    P3147 [USACO16OPEN]262144 题目描述 Bessie likes downloading games to play on her cell phone, even though ...

  6. 微信开发出现 redirect-uri參数错误原因是设置回调页面域名不要加HTTP://

    OAuth2.0 网页授权设置.回调页面域名不要加HTTP:// NND  微信的研发.你程序处理下非常麻烦吗?给个提示非常麻烦吗?让我查了1个多小时.

  7. bzoj1296: [SCOI2009]粉刷匠(DP)

    1296: [SCOI2009]粉刷匠 题目:传送门 题解: DP新姿势:dp套dp 我们先单独处理每个串,然后再放到全局更新: f[i][k]表示当前串枚举到第i个位置,用了k次机会 F[i][j] ...

  8. Python 序列化处理

    序列化 文件为dump 字符串为dumps dumps()方法返回一个str,内容就是标准的JSON loads()方法将其还原 在程序运行的过程中,所有的变量都是在内存 d = dict(name= ...

  9. django 笔记12 session

    第一步写好函数,然后生成数据库session表 python manage.py makemigrations python manage.py migrate session原理: .Session ...

  10. [NOIP2015模拟10.22] 最大子矩阵 解题报告(单调栈)

    Description 我们将矩阵A中位于第i行第j列的元素记作A[i,j].一个矩阵A是酷的仅当它满足下面的条件:       A[1,1]+A[r,s]<=A[1,s]+A[r,1](r,s ...