JNDI理解

看了好多博客,发现老是能把JNDI和数据库连道一块儿来说,固然说的也没有错,不过DB链接只是JNDI的一个很小很小的应用。查阅官方资料总结出下面的内容:html

1 JNDI解释

1.1 命名概念

JNDI即Java Naming and Directory Interface(JAVA命名和目录接口),那么java命名目的就是为了记录一些不方便记录的内容,就像人的名字或DNS中的域名与IP的关系。java

1.2 名字的概念

一个命名的展现由名字和分隔符提现:mysql

例如:sql

image

一样命名空间也是 数据库

1.3 绑定

在上面的示例中,一个标识符最终都要绑定到具体的内容:例如/usr/hello绑定的是hello目录;sales.wiz.com绑定的是x.x.x.x样式的IP地址安全

 

2 JNDI概述

2.1 JNDI结构

I(T`8J2[KW0YTX@HAPREZTW

JNDI由JNDI API、命名管理、JNDI SPI(service provider interface)服务提供的接口。咱们的应用能够经过JNDI的API去访问相关服务提供的接口。 服务器

咱们要使用JNDI,必需要有服务提供方,咱们经常使用的就是JDBC驱动提供数据库链接服务,而后咱们配置JNDI链接。。 并发

JDK也为咱们提供了一些服务接口: oracle

1. LDAP (Lightweight Directory Access Protocol) 轻量级目录访问协议 ide

2. CORBA (Common Object Request Broker Architecture) 公共对象请求代理结构服务

3. RMI(Java Remote Method Invocation)JAVA远程远程方法调用注册

4. DNS(Domain Name Service)域名服务

2.2 本身的理解

JNDI并非与数据源链接绑定在一块儿的。从数据源链接认识JNDI,可是认识完JNDI后,必定要跳出来,JNDI是一个命名目录接口,提供与外界的一个访问关系,只要相关应用、设备能提供服务,那么咱们就能够经过JNDI来链接处理。

例如:链接打印机、链接注册表等。

更多的应用要本身来探索。

 

3 优秀博文描述片断

3.1 jndi的做用,为何要有jndi

地址:http://blog.csdn.net/zjlolife/article/details/8881154

总结:
J2EE 规范要求全部 J2EE 容器都要提供 JNDI 规范的实现。//sun 果真喜欢制定规范JNDI 在 J2EE 中的角色就是“交换机” —— J2EE 组件在运行时间接地查找其余组件、资源或服务的通用机制。在多数状况下,提供 JNDI 供应者的容器能够充当有限的数据存储,这样管理员就能够设置应用程序的执行属性,并让其余应用程序引用这些属性(Java 管理扩展(Java Management Extensions,JMX)也能够用做这个目的)。JNDI 在 J2EE 应用程序中的主要角色就是提供间接层,这样组件就能够发现所须要的资源,而不用了解这些间接性。
在 J2EE 中,JNDI 是把 J2EE 应用程序合在一块儿的粘合剂,JNDI 提供的间接寻址容许跨企业交付可伸缩的、功能强大且很灵活的应用程序。这是 J2EE 的承诺,并且通过一些计划和预先考虑,这个承诺是彻底能够实现的。

从上面的文章中能够看出:
一、JNDI 提出的目的是为了解藕,是为了开发更加容易维护,容易扩展,容易部署的应用。
二、JNDI 是一个sun提出的一个规范(相似于jdbc),具体的实现是各个j2ee容器提供商,sun   只是要求,j2ee容器必须有JNDI这样的功能。
三、JNDI 在j2ee系统中的角色是“交换机”,是J2EE组件在运行时间接地查找其余组件、资源或服务的通用机制。
四、JNDI 是经过资源的名字来查找的,资源的名字在整个j2ee应用中(j2ee容器中)是惟一的。

 

3.2 JNDI全面总结

地址:http://blog.csdn.net/kingmax54212008/article/details/52229642

3.2.1 链接数据库用JNDI时的运行机制

一、 首先程序代码获取初始化的 JNDI 环境而且调用 Context.lookup() 方法从 JNDI 服务提供者那里获一个 DataSource 对象

二、 中间层 JNDI 服务提供者返回一个 DataSource 对象给当前的 Java 应用程序这个 DataSource 对象表明了中间层服务上现存的缓冲数据源

三、 应用程序调用 DataSource 对象的 getConnection() 方法

四、 当 DataSource 对象的 getConnection() 方法被调用时,中间层服务器将查询数据库 链接缓冲池中有没有 PooledConnection 接口的实例对象。这个 PooledConnection 对象将被用于与数据库创建物理上的数据库链接

五、 若是在缓冲池中命中了一个 PooledCoonection 对象那么链接缓冲池将简单地更 新内部的缓冲链接队列并将该 PooledConnection 对象返回。若是在缓冲池内没 有找到现成的 PooledConnection 对象,那么 ConnectionPoolDataSource 接口将会被 用来产生一个新的 PooledConnection 对象并将它返回以便应用程序使用

6。 中间层服务器调用 PooledConnection 对象的 getConnection() 方法以便返还一个 java.sql.Connection 对象给当前的 Java 应用程序

七、 当中间层服务器调用 PooledConnection 对象的 getConnection() 方法时, JDBC 数据 库驱动程序将会建立一个 Connection 对象而且把它返回中间层服务器

八、 中间层服务器将 Connection 对象返回给应用程序 Java 应用程序,能够认为这个 Connection 对象是一个普通的 JDBC Connection 对象使用它能够和数据库创建。事 实上的链接与数据库引擎产生交互操做 。

九、 当应用程序不须要使用 Connection 对象时,能够调用 Connection 接口的 close() 方 法。请注意这种状况下 close() 方法并无关闭事实上的数据库链接,仅仅是释 放了被应用程序占用的数据库链接,并将它还给数据库链接缓冲池,数据库链接 缓冲池会自动将这个数据库链接交给请求队列中下一个的应用程序使用。

3.2.2 JNDI原理

在DataSource中事先创建多个数据库链接,保存在数据库链接池中。当程序访问数据库时,只用从链接池中取空闲状态的数据库链接便可,访问结束,销毁资源,数据库链接从新回到链接池,这与每次去直接访问数据库相比,会节省大量时间和资源。
         JNDI( Java Naming and Directory Interface ),是Java平台的一个标准扩展,提供了一组接口、类和关于命名空间的概念。如同其它不少Java技术同样,JDNI是provider-based的技术,暴露了一个 API和一个服务供应接口(SPI)。这意味着任何基于名字的技术都能经过JNDI而提供服务,只要JNDI支持这项技术。JNDI目前所支持的技术包括 LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等等。不少J2EE技术,包括EJB都依靠JNDI来组织和定位实体。能够把它理解为一种将对象和名字捆绑的技术,对象工厂负责生产出对象,这些对象都和惟一的名字绑在一块儿,外部资源能够经过名字得到某对象的引用。

          在javax.naming的包包中提供Context接口,提供了两个很好用的方法:
<1> void bind( String name , Object object )
        将名称绑定到对象。全部中间上下文和目标上下文(由该名称最终原子组件之外的其余全部组件指定)都必须已经存在。
<2>Object lookup( String name )
       检索指定的对象。若是 name为空,则返回此上下文的一个新实例(该实例表示与此上下文相同的命名上下文,但其环境能够独立地进行修改,并且能够并发访问)。

3.2.3 代码示例

3.2.3.1 TOMCAT数据源配置(Server.xml和Context.xml两种方式)

Context.xml方式:

<Resource name="jdbc/MySQL" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="60" wait_timeout="18800" timeBetweenEvictionRunsMillis="300000" minEvictableIdleTimeMillis="600000"
               username="root" password="jdzxdb" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/sxtele?comautoReconnect=true&amp;failOverReadOnly=false"  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/>
<Resource name="jdbc/db2" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="60" wait_timeout="18800" timeBetweenEvictionRunsMillis="300000" minEvictableIdleTimeMillis="600000"
               username="lcgluser" password="lcgluser" driverClassName="com.ibm.db2.jcc.DB2Driver"
               url="jdbc:db2://133.64.46.65:50000/STEDWDB"  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/>

name 表示指定的jndi名称
auth 表示认证方式,通常为Container
type 表示数据源床型,使用标准的javax.sql.DataSource
maxActive 表示链接池当中最大的数据库链接
maxIdle 表示最大的空闲链接数
maxWait 当池的数据库链接已经被占用的时候,最大等待时间
logAbandoned 表示被丢弃的数据库链接是否作记录,以便跟踪
username 表示数据库用户名
password 表示数据库用户的密码
driverClassName 表示JDBC DRIVER
url 表示数据库URL地址

注意,这里你配置的name值要和程序中使用的是同样的,好比按照这个例子,程序就应该是这样的

String gENV = "java:comp/env/";   
Context ctx = new InitialContext();     
      DataSource ds = (DataSource)ctx .lookup(gENV+"jdbc/mysql");   
      Connection conn = ds.getConnection(); 
String gENV = "java:comp/env/";
Context ctx = new InitialContext();
      DataSource ds = (DataSource)ctx.lookup(gENV+"jdbc/db2");
      Connection conn = ds.getConnection();

Server.xml方式

Tomcat-6.0.26\conf\context.xml中的配置:在<Host></Host>中添加以下配置
  <Context path="/sljx" reloadable="true"  docBase="sljx"   crossContext="true" 
debug="0">
               <Resource 
                   name="jdbc/oracle"
                   type="javax.sql.DataSource"
                   auth="Container"
                   username="sljx"
                   password="sljx"
                   driverClassName="oracle.jdbc.driver.OracleDriver"
                   maxIdle="3000"
                   maxWait="5000"
                   url="jdbc:oracle:thin:@localhost:1521:jadetrus"
                   autoReconnect="true"
                   maxActive="1000"/>
      </Context>

3.2.4 JNDI包概述

javax.naming:命名操做;
javax.naming.directory:目录操做;
javax.naming.event:在命名目录服务器中请求事件通知;
javax.naming.ldap:提供LDAP支持;
javax.naming.spi:容许动态插入不一样实现。

3.2.5 经常使用的JNDI操做

void bind(String sName,Object object);――绑定:把名称同对象关联的过程
void rebind(String sName,Object object);――从新绑定:用来把对象同一个已经存在的名称从新绑定
void unbind(String sName);――释放:用来把对象从目录中释放出来
void lookup(String sName,Object object);――查找:返回目录总的一个对象
void rename(String sOldName,String sNewName);――重命名:用来修改对象名称绑定的名称

3.2.6 主要概念

-          名字(Names),在名字系统中实际对象的代号,如文件名,域名等,它会被用来查找关联的对象。不一样的系统中会有不一样的命名规范,如文件系统采用“\”来表示层级,而DNS则使用“.”。

-          绑定(Bindings),名字和实际对象的关联。

-          引用和地址(References and Addresses),当对象不能直接被存储在名字系统时,就必须使用引用,经过引用找到实际的对象。在系统中,保存的引用的内容被称为地址。引用还有另外一个用处:在名字系统中,缺乏象关系数据库中外键的概念。经过使用引用,能够做为外键的一个取代办法。

-          上下文(Context),它是一个名字-对象集合,提供了与名字系统交互的主要操做,如查找、绑定、去绑定。子上下文(subcontext)与它的关系相似文件系统中目录和子目录的关系,子上下文被包含在一个上下文中,经过父上下文中的一个名字与子上下文关联。

-          名字系统和名字空间(Naming Systems and Namespaces),名字系统是相同类型的上下文的集合,它提供名字服务;名字空间,是名字系统中的名字集合,如文件系统的文件名和目录。

Directory service       目录服务是名字服务的扩展,它除了关联名字和对象,还容许对象包含属性。目录系统一般以层次结构组织数据。在目录服务中的主要概念:

-          属性(Attributes),它属于目录对象,它是(名字,值)对,属性能够有多个值。

-          目录和目录服务(Directories and Directory Services),目录是目录对象的集合;目录服务则提供与目录相关的服务,建立、删除和修改存放在目录中的对象的属性。

-          查找和查找过滤器(Searches and Search Filters),获取目录对象的操做就是查找;过滤器是相似查找条件的对象。

3.2.7 注册JNDI提供者

在使用JNDI以前,须要先获取JNDI的提供者,并在系统注册它。与JNDI相关的系统属性在javax.naming.Context中定义,经常使用的属性:

-          java.naming.factory.initial,服务提供者用来建立InitialContext的类名。

-          java.naming.provider.url,用来配置InitialContext的初始url

-          java.naming.factory.object,用来建立name-to-object映射的类,用于NameClassPair和References。

-          java.naming.factory.state,用来建立jndi state的类

对于目录服务,因为通常须要安全设置,还一般使用:

-          java.naming.security.authentication,安全类型,三个值:none,simple或strong。

-          java.naming.security.principal,认证信息。

-          java.naming.security.credentials,证书信息。

-          java.naming.security.protocol,安全协议名。

使用System.setProperty注册,若是程序不显示说明,那么java会在classpath内查找jdni.properties文件来完成注册。jdni.properties例子:

java.naming.factory.initial=com.codeline.db.MockInitialContextFactory

 

参考:

[1]命名空间及目录的概念理解:https://docs.oracle.com/javase/tutorial/jndi/concepts/index.html  推荐看看

[2]JNDI概述:https://docs.oracle.com/javase/tutorial/jndi/overview/index.html  推荐看看

[3]JNDI应用配置:https://docs.oracle.com/javase/tutorial/jndi/software/index.html 推荐看看

[4]JNDI帮助主页:https://docs.oracle.com/javase/tutorial/jndi/index.html

[5]JNDI教程:https://docs.oracle.com/javase/jndi/tutorial/

[6]通俗易懂全面的JNDI介绍:http://blog.csdn.net/kingmax54212008/article/details/52229642

相关文章
相关标签/搜索