`

关于JNDI的简介

阅读更多

1.       什么是 JNDI ( Java Naming and Directory Interface )

JNDI 是用于访问不同命名和目录服务的统一 API 接口;

2.       JNDI 的架构和原理

      1.       架构:

         第一层: java 代码,是访问 JNDI 的代码;

         第二层: JNDI API :统一的命名和目录服务接口

         第三层: JNDI Naming Manager : JNDI 管理器

         第四层: JNDI SPI :用于构建 JNDI 实现的框架,能够动态的插入命名和目录服务提供商的产品;

         第五层:命名和目录服务提供商的产品;

         命名和目录服务提供商的产品 , 例如: DNS,LDAP,NIS,NDS……..; 因为这些产品都是不同的提供商提供的产品,所以他们的命名和目录服务的标准不一致,各个目录服务采用的访问协议也是不一样的,所以,要是直接访问他们的话,就要编写不同的 java 代码来访问他们;因此, JNDI SPI 就解决了这个问题,它能动态的插入这些命名和目录服务,能够将其协议专属的目录产品集成到系统中,使得我们能只需要调用一个统一的 javaAPI 就能够访问插入的产品了;

         2 .原理:

               JNDI 其实很好理解,他就是一个树状的结构,它的最顶是一个 initialContext 节点,然后它的下面就是绑定的一些对象或是一些 subContext ,用 JNDI 树就能够查找到树中每一个绑定上的节点上的对象的引用;

3. 怎样连接到 JNDI 上?

                  Environment environment = new Environment() ;// 创建一个环境对象

                   environment.setProviderurl(“t3://www.blogjava.net”) ;

                   environment.setSecurityPrincipal(“todd”) ;// 认证的用户名

                   environment.setSecurityCredentials(“841026”) ;// 密码

                   Context context = environment.getInitialContext() ;

         // 创建一个 subContext 并绑定一个对象:

                   Context subContext = context.createSubcontext(“subContext”) ;

                   subContext.rebind(“newObject”,object) ;// 绑定的对象必须是可序列化的

                   subContext.close() ;

                   context.close() ;

4. 如何通过 JNDI 查找 bind 的对象?

         Object object = context.lookup(“User”) ;

         // 把 user 窄化到原型

         User user = (User)javax.rmi.PortableRemoteObject.narrow(object, User.class) ;

         context.close() ;

 

 

 

一、JNDI是什么?

      JNDI--Java 命名和目录接口(Java Naming and Directory Interface),是一组在Java应用中访问命名和目录服务的API。

二、JNDI好处

      解耦:通过注册、查找JNDI服务,可以直接使用服务,而无需关心服务提供者,这样程序不至于与访问的资源耦合!
JNDI优点 写道
JNDI优点
  包含了大量的命名和目录服务,使用通用接口来访问不同种类的服务;   可以同时连接到多个命名或目录服务上;   建立起逻辑关联,允许把名称同Java对象或资源关联起来,而不必知道对象或资源的物理ID。   JNDI程序包:   javax.naming:命名操作;   javax.naming.directory:目录操作;   javax.naming.event:在命名目录服务器中请求事件通知;   javax.naming.ldap:提供LDAP支持;   javax.naming.spi:允许动态插入不同实现。   利用JNDI的命名与服务功能来满足企业级APIs对命名与服务的访问,诸如EJBs、JMS、JDBC 2.0以及IIOP上的RMI通过JNDI来使用CORBA的命名服务。

 

三、JNDI架构与原理

      相比较架构与原理,更关注与使用,故略!

四、JNDI使用

      在J2EE容器(如weblogic、websphere、jboss等)中使用:

    在weblogic环境下查找tuxedo 连接    

//在weblogic环境查找tuxedo连接
Context ctx = new InitialContext();
TuxedoConnectionFactory tuxedoFactory = (TuxedoConnectionFactory) ctx.lookup("tuxedo.services.TuxedoConnection");

   在web容器查找数据源

Context ctx=new InitialContext();
DataSource ds=(Datasource)ctx.lookup("java:comp/env/jdbc/mydatasource");

   重点关注Context ctx = new InitialContext(),上面的代码在容器下能够很好的工作,尤其是查找数据源的代码,无论是在tomcat,还是在weblogic、jboss,但如果脱离了容器,我们将得到异常“NoInitialContextException”,这是为什么呢?

   原因很简单,就是不存在相关的context,其本质是JNDI的服务提供者环境,即谁将提供此环境!

   为了能够使上面的代码工作,我们需要使用带参的构造子InitialContext(Hashtable),指定JNDI服务提供者环境信息,以weblogic环境为例:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);

    但上面的代码不适合WebSphere、jboss等环境,原因在于所需环境信息不同,那么,Context ctx = new InitialContext()是如何做到在各个j2ee容器下有效地呢?原因在于这个默认的构造子是从System.properties读取

相关的环境信息的,由此不难猜出在各种J2EE容器下,如weblogic、jboss,它们都自己为自己设置了相应的信息!下面是一个关于System.properties设置JNDI服务环境的例子:

System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
System.setProperty(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext ctx = new InitialContext();

   较为详细点的信息可以参看这里!

五、借助Spring完成JNDI查找

    对于手头的weblogic,给出常用的两个查找例子,做个备忘吧!

查找tuxedo connnection:

<bean id="tuxedoConnFactory" class="org.springframework.jndi.JndiObjectFactoryBean">  
      <property name="jndiName">
            <value>tuxedo/services/TuxedoConnection</value>
      </property>
      <property name="resourceRef">
          <value>false</value>
     </property>
     <property name="jndiEnvironment">
       <props>
            <!-- The value of Context.PROVIDER_URL -->
            <prop key="java.naming.provider.url">t3://localhost:7001</prop>
            <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
        </props>
      </property>
</bean>

 

    查找DataSource:

<bean id="tuxedoConnFactory" class="org.springframework.jndi.JndiObjectFactoryBean">  
      <property name="jndiName">
            <value>java:comp/env/jdbc/myDatasource</value>
      </property>
</bean>

   更多关于spring jndi配置参看这里,下面是其摘录:
Spring中对于JNDI的访问,提供了便捷的方法,在Spring的org.springframework.jndi包中包含了所有的类。其中提供了一下核心类:

(1)JndiTemplate:它是这个包的核心类,用来简化对JNDI的操作。它提供了对于lookup、bind方法。同时,允许JndiCallback接口的实现在其提供的JNDI上下文中执行任何操作。

使用JndiTemplate实现InitialContext环境变量的配置

<bean id="queueTarget" class="org.springframework.jndi.JndiObjectTargetSource">

<property name="jndiName">

<value>queue/testQueue</value>

</property>

<property name="jndiTemplate">

<ref local="jndiTemplate"/>

</property>

</bean>

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">

<property name="environment">

<props>

<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>

<prop key="java.naming.provider.url">jnp://localhost:1099</prop>

<prop key="java.naming.factory.url.pkgs">org.jboss.namingrg.jnp.interfaces</prop>

</props>

</property>

</bean>

(2)JndiObjectTargetSource

使用JndiObjectTargetSource,例如

<bean id="queueTarget" class="org.springframework.jndi.JndiObjectTargetSource">

<property name="jndiName">

<value>queue/testQueue</value>

</property>

</bean>

(3)JndiObjectFactoryBean:

使用JndiObjectFactoryBean,例如

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>java:/MySqlDS</value>

</property>

</bean>

总结(事例):

数据源的配置:

(1)配置可以访问到同一应用服务器的jndi数据源

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>jdbc/cqccms</value>

</property>

</bean>

(2)配置能访问远程jndi数据源

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>jdbc/cqccms</value>

</property>

<property name="jndiEnvironment">

<props>

<prop key="java.naming.factory.initial">

weblogic.jndi.WLInitialContextFactory

</prop>

<prop key="java.naming.provider.url">t3://172.16.101.42:7001</prop>

<prop key="java.naming.security.principal">weblogic</prop>

<prop key="java.naming.security.credentials">weblogic</prop>

</props>

</property>

</bean>

事务的配置:

不过事务对象远程访问好像没那么顺利,同理查看 org.springframework.transaction.jta.JtaTransactionManager类,没有发现上述方法,不过看到了setJndiTemplate()方法,也不错现配置一个jndiTemplate,如下:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate" singleton="true"

lazy-init="default" autowire="default" dependency-check="default">

<property name="environment">

<props>

<prop key="java.naming.factory.initial">

weblogic.jndi.WLInitialContextFactory

</prop>

<prop key="java.naming.provider.url">t3://172.16.101.42:7001</prop>

<prop key="java.naming.security.principal">weblogic</prop>

<prop key="java.naming.security.credentials">weblogic</prop>

</props>

</property>

</bean>

然后在配置一下transactionManager,如下

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" singleton="true"

lazy-init="default" autowire="default" dependency-check="default">

<property name="jndiTemplate">

<ref local="jndiTemplate" />

</property>

<property name="userTransactionName">

<value>weblogic/transaction/UserTransaction</value>

</property>

</bean>

不过JtaTransactionManager默认找jndi name为UserTransaction的jta对象,在同一应用服务器上可以,远程访问不到,后直接查看weblogic的jndi树找到这个 jndi名weblogic/transaction/UserTransaction,配置上测试果然成功。

分享到:
评论

相关推荐

    JNDI简介

    关于JNDI的用法的一些简单介绍!

    JNDI简介与SPI实现

    NULL 博文链接:https://shift-alt-ctrl.iteye.com/blog/1971329

    Jndi的使用简介

    简要描述项目中Jndi的使用过程,完成servlet通过池连接的方式访问数据库

    J2EE JNDI配置原理详解 JBOSS安装配置 Maven入门 Ant使用入门

    1.5 JSP 隐式对象简介 1.6 Java解析XML的四种方法 1.7 struts1和truts2比较 1.8 Tomcat5启动流程与配置详解 1.9 HttpServlet详解 1.10 Ant使用入门 1.11 Maven Ant之间的比较 1.12 详解MANIFEST.MF文件 1.13...

    JNDI参考资料.doc

    JNDI参考资料,这里讲述了JNDI的简介,原理,以及连接池等技术

    JNDI简介_动力节点Java学院整理

    主要介绍了JNDI简介,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    JNDI:JNDI注入利用工具

    简介 基本信息 获取服务器基础信息 打印出System.getProperties()中的信息 命令 命令执行 反射调用forkandexec执行命令 数据源黑客 获取Spring DataSource明文 获取缓存在某些中的数据源 目录列表 目录遍历 使用...

    JNDI,JTA和JMS简介

    主要介绍了JNDI,JTA和JMS的相关内容,包括中文释义,概念解释等,需要的朋友可以了解下。

    SpringMVC+JNDI+Tomcat配置数据源

    一、 简介 二、 tomcat配置jndi有三种方式。 第一种:单个应用独享数据源 第二种:配置全局JNDI数据源,应用到单个应用 三、 数据源配置在Tomcat/conf/ context.xml 文件或者 server.xml 文件 中的区别 四、 常见的...

    服务器端接口编程.pptx

    1.JNDI 简介 服务器端接口编程全文共45页,当前为第5页。 分子间力:分子与分子间的相互作用力。 类型:范德华力、氢键、 π-π作用等 化学键: 离子键 共价键 类金属键 分类: 分子中相邻原子间强力的直接的相互...

    JBoss3.0下配置和部署EJB简介

    1.JBoss简介JBoss是一个运行EJB的J2EE应用服务器。它是开放源代码的项目,遵循最新的J2EE规范。从JBoss项目开始至今,它已经从一个EJB容器发展成为一个基于的J2EE的一个web操作系统(operatingsystemforweb),它...

    JSP高级编程          

    2.1 EJB 技术简介 2.2 EJB 体系结构(一) 2.3 EJB 体系结构(二) 2.4 如何开发EJB(一) 2.5 如何开发EJB(二) 2.6 本章小结 第3 章 EJB 技术进阶 3.1 实体EJB 的开发技术之一CMP EJB 3.2 实体EJB 的开发技术之二——BMP ...

    JSP高级编程(全)

    2.1 EJB 技术简介 2.2 EJB 体系结构(一) 2.3 EJB 体系结构(二) 2.4 如何开发EJB(一) 2.5 如何开发EJB(二) 2.6 本章小结 第3 章 EJB 技术进阶 3.1 实体EJB 的开发技术之一CMP EJB 3.2 实体EJB 的开发技术之二——BMP ...

    Activiti6.0.x-中文版用户指南

    简介 o 1.1。执照 o 1.2。下载 o 1.3。资料来源 o 1.4。所需软件  1.4.1。JDK 7+  1.4.2。集成开发环境 o 1.5。报告问题 o 1.6。实验功能 o 1.7。内部实施类 • 2.入门 o 2.1。一分钟版 o 2.2。Activiti设置 o ...

    迫于目前现有的weblogic工具没怎么更新、payloayjdk适用版本等问题,所以基于superman18、sp4zcmd等

    简介: 迫于目前现有的weblogic工具没怎么更新、payloayjdk适用版本等问题,所以基于superman18、sp4zcmd等项目,写一个weblogic工具,工具运行版本要求jdk 8(深信服深蓝实验室天威战队强力驱动) 支持漏洞: CVE-...

    j2ee基础知识

    J2EE简介及学习方法 J2EE基础技术  XML、RMI、JNDI 、JMS

    J2EE的13种核心技术简介

    支撑J2EE的13种核心技术:JDBC, JNDI, EJBs, RMI, JSP, Java servlets, XML, JMS, Java IDL, JTS, JTA, JavaMail 和 JAF.

    GeoServer开发手册系列

    配置Jetty的JNDI资源 19 Eclipse首选项 20 代码格式化 21 代码模板 22 文本编辑器 22 编译器 23 OWS服务 24 OWS服务概览 24 实现一个简单的OWS服务 24 建立 25 创建插件 27 试一试 30 REST服务 34 简介 34 RESTful...

    log4j实用配置扩展

    主要讲述log4j的简介,以及log4j的配置和在实际应用的使用。如果您不知道如何配置log4j,那么这本书将对您有很大的帮助。

Global site tag (gtag.js) - Google Analytics