`
menjoy
  • 浏览: 421982 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

J2EE or J2SE? JNDI works with both

    博客分类:
  • Java
阅读更多

J2EE or J2SE? JNDI works with both

  JNDI(Java Naming and Directory Interface), 允许应用通过一个通用的接口来访问各种命名和目录服务。下面的特征表征了JNDI的架构。如同JDBC(Java Database Connectivity),JNDI并不是一种服务,而是一套接口;它允许应用使用标准API来访问很多不同的目录服务供应商。尽管Sun公司提供了适配器,比如LADP、DNS和CORBA,以连接已有的目录服务供应商,但是就如同JDK包含JDBC一样,它包含了JNDI接口,但并不包含JNDI服务供应商。然而,您可以选择使用免费或者开源JNDI供应商中的一种到您的J2SE应用中去。

  JNDI是整合J2EE应用的黏合剂。JNDI被设计用来支持具有较高动态组装和部署的那些应用,可以在不用重建整个系统的条件下经常的添加和更新各种组件。命名服务则通过作为一个组件注册中心来帮助组织企业级的应用。J2EE应用一般在如下一些方面使用JNDI:

  # 在一个集中、分级数据库中储存应用配置信息

  # 作为在不同应用组件间共享的活动对象的仓库,这些组件能够运行在不同的JVM或者不同的系统中

  # 作为已有目录服务例如LDAP的接口(通过使用特别的方式来访问外部的服务)

  象J2EE应用一样,更大、更多的动态J2SE应用将得益于由动态目录服务带来的松偶合以及动态绑定特点。


一个简单的JNDI例子

  从JNDI命名空间中储存和回溯对象是简单和易懂的;首先,获得JNDI的命名上下文(naming context),然后,使用bind()和lookup()方法来储存和回溯对象,就象Listing 1中显示的那样:

Listing 1. Store and retrieve objects from a JNDI namespace

  import javax.naming.*;

  public void createName() throws NamingException {
    Context context = new InitialContext();
    context.bind("/config/applicationName", "MyApp");
  }

  public String getName() throws NamingException {
    Context context = new InitialContext();
    return (String) context.lookup("/config/applicationName");
  }

  Listing 1演示的是最通常的JNDI操作:创建一个JNDI上下文,为该上下文绑定对象,从该上下文中回溯对象。需要注意的是,JNDI命名空间以及客户端可能驻留在不同的JVM中,因此bind()和lookup()方法的调用可能发生在不同的JVM中。JNDI提供商通过使用一系列的技术,包括序列化,来保证对象能够在不同的JVM之间移动,并且可以回溯为它原来的形式。

  Listing 1的代码片断有几个隐藏的假设:JNDI是如何知道在创建上下文的时候该使用哪个提供商?对于需要安全验证的提供商,信任书又从哪里来呢?一般来说,您可以通过在系统属性中设定JNDI相关的属性,或者把它们设定到jndi.properties文件中来制定提供商以及其它连接是所需要的参数。当然,任何的提供商都不能随意的绑定和回溯对象。例如,一些提供商,比如DNS提供商,对象类型是只读的,而有些提供商却可以提供更加灵活的对象类型。大多数卖方提供的供应商能储存和回溯那些实现了以下任何一个接口的对象:java.io.Serializable, java.rmi.Remote, 或者 javax.naming.Referenceable。

隐藏的JNDI供应商
  具有以上特征的JNDI供应商有相同的地方:它们都通过代理来访问外部的目录服务,比如LADP。然而,这里面没有包含一种重要的JNDI供应商类型:内嵌在J2EE容器中的JNDI供应商,它把目录信息储存在内部的数据库中。当我们讨论在J2EE应用中使用JNDI时,通常指的就是这种容器提供的供应商。


J2EE是如何使用JNDi的?

  J2EE应用是以组件形式组装起来的。组件的配置以及互相之间的连接的方式是在部署的时候指定的;大多数的信息被储存在JNDI的命名空间中。J2EE应用使用JNDI来储存配置信息(比如string和numeric类型的常量),无状态的对象(包括对象工厂),以及EJB的home接口。

  JNDI可以看做是黏合剂,它允许您以组件形式比如servlets、Jsps以及EJBs,构建J2EE应用。在J2EE应用中,每个组件不是通过静态的链接而是通过JNDI查找来找寻其它的组件的。J2EE应用还允许在维护类型和链接安全性时进行部署期的绑定,这是通过每个组件报告一份它将需要的其它组件以及资源列表实现的。部署保证在应用中每次导入都有相关正确的组件类型。J2EE容器提供工具来帮助您正确的完成这项工作。


How can J2SE apps use JNDI?

  如同J2EE应用一样,J2SE应用能够将JNDI作为一个储存了命名配置参数、对象以及对象工厂的仓库。工厂创建模式和JNDI可以很好的配合工作,你能够在JNDI命名空间中只保存工厂对象。J2SE应用能够使用JNDI来替换RMI(远程方法调用)来达到更加强大、功能丰富以及集中化的特点。

  大多数的J2SE应用从配置文件中来获取它们的配置信息,这些配置文件要么是属性文件要么是XML文档。这些配置文件指定了所有的配置信息;一些更加复杂的应用为实例化对象的条件比如类名和构造器参数在配置文件中储存信息。

  使用JNDI来储存常量、对象以及对象工厂比传统的配置存储机制有一些优势。因为大多数的JNDI供应商都是支持网络访问的,您就不必为保证每个分散的应用主机上配置文件的一致性而花费精力。此外,使用反射机制来实例化对象是件凌乱的事情,并且需要比简单的通过JNDI命名空间回溯对象更多的代码(一般是更多的出错恢复代码)。使用JNDI并不能避免从配置信息中实例化对象的需要(通常在应用启动,你获得命名空间的时候),这种复杂程度已经从大多数的应用代码中剥离出去了,这样就能简化从JNDI命名空间中回溯期望的对象的程度。

  另外一个在分布式应用中使用JNDI而不是配置文件的原因是配置文件中的信息可能是敏感的信息,比如访问数据库的密码。将Datasource储存在JNDI的名称空间中,可以不用为整个应用设置密码就完成对整个应用的数据库连接。(比如,PoolMan连接池,一个广泛被使用的开源项目,就是将Datasource对象储存在JNDI名称空间中的。)

  为了在您的J2SE应用中使用JNDI,您首先需要一个JNDI供应商,因为JDK并没有包含。如果您只是想用JNDI来访问外部的目录比如LDAP,那么您可以使用由Sun提供的供应商中的一个。但是通常来说,您将希望拥有一个独立的供应商,可以有许多的选项供您选择。


独立的JNDI供应商

  开放原码J2EE服务器JBoss包含了一个JNDI供应商(JNP),它能作为独立服务运行;他提供非常出色的轻量级网络访问JNDI服务。JNP使用记忆在内存中的数据库来存储对象,所以命名空间的内容在服务重新启动时将不会保存。您可以非常容易的靠它自己来运行JNP,或者通过配置JBoss容器使只有在JNP服务的时候来启动它。

选择1:配置JNP服务以作为JBoss的一项服务
  JBoss应用服务器建立在JMX(Java管理扩展)框架上;该框架允许将应用服务模块化为JMX mbeans,这样可以独立的启动和管理它们。文件jboss.jcml包含了在容器启动的时候装载的一个mbeans列表。JBoss缺省的配置包含超过50个mbeans,但是如果您配置jboss.jcml文件应该只包含单独的如Listing 2中的配置,然后启动JBoss服务器,那么服务器将只装载JNDI供应商,其它的任何J2EE应用服务将不会被装载:

Listing 2. 仅包含JNDI的jboss.jcml文件

<?xml version="1.0" encoding="UTF-8"?>
<server>
  <mbean code="org.jboss.naming.NamingService"
         name="DefaultDomain:service=Naming">
    <attribute name="Port">1099</attribute>
  </mbean>
</server>

选择2:配置JNP服务器使得它单独运行
  JNP还可以作为一个单独存在的应用服务器。为达到这个目的,您需要下面两个jar配置文件:

  # jnpserver.jar -- 在lib/ext目录
  # log4j.jar -- 广泛被使用的日志工具,来自Apache Jakarta项目;在JBoss的lib/ext目录

  此外,您还需要一个log4j.properties文件;Listing 3显示了一个简单的情况。该文件可以通过如下的途径来访问:

Listing 3. 简单的log4j.properties文件

# Use a ConsoleAppender -- write log data to standard out
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

  为了在运行模式下运行JNP服务器,请确保log4j.jar文件、jnpserver.jar文件以及包含log4j.properties文件的目录都可以在您的classpath找到。然后,运行如下命令启动JNP服务器:

  java org.jnp.server.Main

  您也可以在您应用的JVM中使用org.jnp.server对象来启动JNDI服务。


使用JNDI服务

  一旦JNP服务器运行起来,您可以通过配置jnp-clinent.jar文件包含在classpath中,以及在系统属性或者jndi.properties文件中指定java.naming.provider.url和java.naming.factory.initial属性,以让您的应用使用JNP。Listing 4显示了一个jndi.properties文件的例子:

Listing 4. jndi.properties文件

java.naming.provider.url=jnphost.mycompany.com:1099
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming

  下面的例子显示了在应用启动的时候如何使用在属性文件中定义好的string、integer这些对象值相关的参数来获得JNDI命名空间,以及应用组件回溯这些属性。简短来说,Listing 5a假设解析XML配置文件的方法并且省略了出错处理的代码:

Listing 5a. 从配置文件中装载JNDI命名空间

   public void loadJNDI() {
    Context context = new InitialContext();
    ConfigItem[] items = getConfigItems();
    for (int i=0; i<items.length; i++) {
      Object o=null;

      if (items[i].getType().equals("Integer"))
        o = Integer.decode(items[i].getValue());
      else if (items[i].getType().equals("String"))
        o = items[i].getValue();
      else if (items[i].getType().equals("Object"))
        o = Class.forName(items[i].getValue()).newInstance();

      context.bind(items[i].getName(), o);
    }
  }


Listing 5b. XML配置文件示例

   <config>
    <item name="config/screen/resolutionX" type="Integer"
          value="1024" />
    <item name="config/screen/resolutionY" type="Integer"
          value="768" />
    <item name="converters/html" type="Object"
          value="com.mycompany.converters.HtmlRenderer" />
    <item name="converters/pdf" type="Object"
          value="com.pdfmonger.PdfRenderer" />
  </config>


Listing 5c. 在JNDI中回溯和使用对象

   public void convert(InputStream in, OutputStream out) {
    // Retrieve the converter object from JNDI
    Context context = new InitialContext();
    Renderer renderer = (Renderer) context.lookup("converters/html");

    // Use the converter object
    renderer.convert(in, out);
  }


  正如您看到的,从JNDI中回溯对象是非常简单和易懂的。通过使用JNDI来存储配置信息、无状态对象或者对象工厂,您可以轻松的创建灵活的应用,同时将负责的配置信息包含在一个单一的地方,甚至对于分布式的应用也是可以的。(如果您的组件是通过JNDI命名空间来访问对象的,那么将它们之间的依赖关系文档化到这些组件的Javadoc中。)

JNDI并不是只为了J2EE而存在的

  尽管JNDI客户端接口也是J2SE的一部分,但是大多数的J2SE应用并没有使用JNDI。那些使用JNDI的通常只是利用它来访问外部的目录服务比如LDAP。然而,J2SE应用还可以使用那些到目前为止只有J2EE应用使用的部署时绑定的特征。随着越来越多的JNDI供应商实现例如JNP的出现,任何需要命名服务的应用都可以拥有它们了。

分享到:
评论

相关推荐

    浅析J2EE,J2SE,J2ME

    分析对比J2EE,J2SE,J2ME,比较简单移动,挺不错一个期刊

    JDK、J2EE、J2SE、J2ME概念详解

    J2EE建立在J2SE之上,增加了大量用于构建分布式、多层架构的企业应用的服务和API,包括Servlet、JSP、EJB、JNDI、JMS、RMI-IIOP等。这些技术使得开发者能够构建复杂的B/S架构应用,同时提供对事务管理、持久化、远程...

    J2EE与J2SE路径获取

    ### J2EE与J2SE路径获取方法详解 在Java开发过程中,无论是针对J2EE还是J2SE项目,路径的获取都是非常基础且重要的环节。本文将详细介绍在J2EE和J2SE环境下如何获取不同类型的路径,并通过具体示例进行说明。 ####...

    解析J2EE、J2SE、J2ME、JDK的区别

    本文向大家简单介绍一下JDK、J2EE、J2SE、J2ME概念及区别,J2EE,J2SE,J2ME是java针对不同的的使用来提供不同的服务,也就是提供不同类型的类库。

    j2ee 与 j2se 和 j2me的区别

    ### Java 平台的不同版本:J2SE、J2EE 和 J2ME 的区别 在 Java 开发领域中,根据不同的应用场景和需求,Java 被分为了几个主要的平台版本,分别是 J2SE(Java 2 Standard Edition)、J2EE(Java 2 Enterprise ...

    java 组件图,j2ee/j2se/j2me差异比较

    这里我们将深入探讨J2EE、J2SE和J2ME之间的区别,并结合JVM、KVM和Card VM,揭示它们各自在Java生态系统中的角色。 首先,J2EE(Java 2 Platform, Enterprise Edition)是Java平台为企业级应用程序设计的。它包含了...

    J2ME-J2EE-J2SE

    Java 技术体系是 Sun Microsystems(后被Oracle收购)推出的一套用于开发和部署跨平台应用程序的框架,它包括三个主要版本:J2ME(Java 2 Micro Edition)、J2EE(Java 2 Platform, Enterprise Edition)和J2SE...

    JavaEE API 最新中英文对照版汉化,JavaSE 1.8,1.6官方API文档,J2EE,J2SE,API文档合集2018-02

    这四套java api文档是本人2018年2月最新收集的,其中三份都是官方最新版,JavaEE API 最新中英文对照版,JavaSE 1.8,1.6官方API文档汉化,J2EE,J2SE,API文档合集

    j2ee,j2se,j2me的区别

    Java 2 Platform, Enterprise Edition (J2EE)、Java 2 Platform, Standard Edition (J2SE) 和 Java 2 Platform, Micro Edition (J2ME) 是 Java 技术的三个不同版本,各自针对不同的应用场景。 J2SE,即Java 2 ...

    java面试题库(j2ee,j2se,ssh,ajax)

    Java 面试题库涵盖了Java J2SE、J2EE以及SSH和Ajax等技术领域,是面试准备的重要参考资料。以下是对这些知识点的详细说明: **Java J2SE**(Java Standard Edition)是Java的核心部分,提供了开发桌面应用程序所需...

    servlet,JSP&J2EE &J2SE笔试题目

    常见java面试题目:包括jsp,servlet,mvc,j2ee等,也是复习不错的资料

    很全的Java 面试题。J2SE+J2EE+JAVAWEB

    J2SE+J2EE+JAVAWEB"的压缩包文件,显然包含了Java开发者在面试中可能遇到的各种问题,涵盖了基础到高级的多个层面。以下是对这些标签和内容的详细解释: **J2SE (Java Standard Edition)**:它是Java平台的基础,...

    j2se.rar_j2EE api_j2se_j2se.c

    这个压缩包"j2se.rar_j2EE api_j2se_j2se.c"显然包含了与 J2EE 和 Java Standard Edition (J2SE) 相关的资源,尤其是 J2EE 的API文档以及可能的 J2SE 相关代码示例。 J2SE 是 Java 平台的核心部分,它为桌面应用和...

    JAVA_API.rar_JAVA_API_j2se j2EE api_j2se api j2ee api_j2se j2ee

    这个"JAVA_API.rar"压缩包包含的是JAVA_API的中文帮助文档,特别是针对j2se(Java 2 Standard Edition)、j2ee(Java 2 Enterprise Edition)以及j2me(Java 2 Micro Edition)的API。 1. **j2se API**:这是Java的...

    java方向程序员面试资料集合,保证对你的面试有利,非常全面,涵盖j2ee,J2se,j2me,内部资料,拼命传出来的,忘各位珍惜

    这份面试资料集合涵盖了Java的三大核心平台:J2EE(Java Platform, Enterprise Edition)、J2SE(Java Platform, Standard Edition)和J2ME(Java Platform, Micro Edition),这些都是Java程序员必须掌握的知识。...

    J2EE J2SE文档

    Java是Oracle公司推出的一种面向对象的、用于开发分布式应用程序的平台,主要分为三个版本:J2SE(Java Standard Edition)、J2EE(Java Enterprise Edition)和J2ME(Java Micro Edition)。本篇将深入探讨J2EE和...

    j2se中实现jndi的控制、管理

    在J2SE(Java 2 Standard Edition)环境中实现JNDI,可以帮助开发者管理和控制各种资源,如数据源、EJB(Enterprise JavaBeans)、邮件服务器等。JNDI主要应用于分布式应用程序,它提供了一个统一的接口,使得应用...

    JDK、J2EE、J2SE、J2ME四个易混淆概念区分

    J2EE与J2SE的主要区别在于,J2SE是个人计算机和服务器应用的基础,而J2EE扩展了这些功能,以满足大型企业系统的复杂需求,如数据库连接、事务处理、安全性等。J2EE SDK 包含J2SE的部分,因为企业级开发需要J2SE的...

Global site tag (gtag.js) - Google Analytics