夢之天堂

          我學故我知,我思故我在;java你我,happy你我——sylilzy

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            3 Posts :: 8 Stories :: 2 Comments :: 0 Trackbacks
          本文基于自己的理解,錯誤之處請提出寶貴意見。版權所有,轉載請注明出處.

          JNDI全攻略之(一)

          關鍵字:JNDI,J2EE,Java,命名和目錄接口,Java Naming and Directory Interface
           
          名詞解釋
              jndi是Java 命名和目錄接口(Java Naming and Directory Interface,JNDI)的簡稱.從一開始就一直是 Java 2 平臺企業版(JEE)的核心技術之一。在JMS,JMail,JDBC,EJB等技術中,就大量應用的這種技術。
              
          為什么會有jndi
              jndi誕生的理由似乎很簡單。隨著分布式應用的發展,遠程訪問對象訪問成為常用的方法。雖然說通過Socket等編程手段仍然可實現遠程通信,但按照模式的理論來說,仍是有其局限性的。RMI技術,RMI-IIOP技術的產生,使遠程對象的查找成為了技術焦點。JNDI技術就應運而生。JNDI技術產生后,就可方便的查找遠程或是本地對象。
           
          JNDI的架構與實現
          r_jndiarch.jpg    
          JNDI的架構與JDBC的架構非常類似.JNDI架構提供了一組標準命名系統的API,這些API在JDK1.3之前是作為一個單獨的擴展包jndi.jar(通過這個地址下載),這個基礎API構建在與SPI之上。這個API提供如下五個包
          在應用程序中,我們實際上只使到用以上幾個包的中類.具體調用類及通信過程對用戶來說是透明的.
          JNDI API提供了訪問不同JNDI服務的一個標準的統一的實現,其具體實現可由不同的Service Provider來完成。前面講的為第一層JNDI API層.
           
          最下層為JNDI SPI API及其具體實現。
           
          圖中所列的一些SPI可從http://java.sun.com/products/jndi/downloads/index.html下載.
          r_jndispi.gif 
          包括了幾個增強和下面的命名/目錄服務提供者:
          • LDAP(Lightweight Directory Access Protocol)服務提供者
          • CORBA COS(Common Object Request Broker Architecture Common Object Services)命名服務提供者 
          • RMI(Java Remote Method Invocation)注冊服務提供者
          • DNS(Domain Name System)服務提供者.
          • FSSP(File System Service Provider)文件系統服務提供者
          • 其它服務提供者
           
          中間層為命名管理層。其功能應該由JNDI SPI來完成。上層為JNDI API,這個API包在Java 2 SDK 1.3及以上的版本中已經包括。
           
          前面講解的只是作為應用程序客戶端的架構實現,其服務端是由SPI對應的公司/廠商來實現的,我們只需將服務端的相關參數傳給JNDI API就可以了,具體調用過程由SPI來完成.
           
           
          JNDI工作原理
           
          下面通過一個示例程序來說明JNDI工作原理(代碼為自解釋).
          /*
          * Created on 2005-3-4
          *
          * To change the template for this generated file go to
          * Window>Preferences>Java>Code Generation>Code and Comments
          */
          package com.
          sily.jndi;

          import java.io.FileInputStream;
          import java.util.Properties;

          import javax.naming.Context;
          import javax.naming.InitialContext;

          /**
          * @author shizy
          *
          * To change the template for this generated type comment go to
          * Window>Preferences>Java>Code Generation>Code and Comments
          */
          public class TestJbossJNDI
          {
          /**
          *
          */
          public TestJbossJNDI
          () {
          super();
          // TODO Auto-generated constructor stub
          }
          public static void main(
          String[] args) { try {
          Properties env =
          new Properties();
          //載入jboss的SPI相關參數,包括初始上下文工廠,服務URL,等等
          env.
          load(new FileInputStream("jbossJndi.properties"));
          env.list(System.out);
          //通過JNDI api 初始化上下文
          InitialContext ctx =
          new javax.naming.InitialContext(env);
          System.
          out.println("Got context");
          //create a subContext
          ctx.
          createSubcontext("/sylilzy");
          ctx.createSubcontext("sylilzy/sily");
          //rebind a object
          ctx.rebind("sylilzy/sily/a", "I am sily a!");
          ctx.rebind("sylilzy/sily/b", "I am sily b!");

          //lookup context
          Context ctx1=(
          Context)ctx.lookup("sylilzy");
          Context ctx2=(Context)ctx1.lookup("/sylilzy/sily");
          ctx2.bind("/sylilzy/g", "this is g");
          //lookup binded object
          Object o
          ;
          o=
          ctx1.lookup("sily/a");
          System.out.println("get object from jndi:"+o);
          //rename the object
          ctx2.
          rename("/sylilzy/g", "g1");
          o=ctx2.lookup("g1");
          System.out.println("get object from jndi:"+o);

          } catch (Exception e
          ) {
          e.
          printStackTrace();
          }
          }
          }
          結果輸出如下:
           
          -- listing properties --
          java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
          java.naming.provider.url=jnp://localhost:1099
          java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
          Got context
          get object from jndi:I am sily a!
          get object from jndi:this is g
           
          程序中jbossJndi.properties文件的內容為:
          java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
          java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
          java.naming.provider.url=jnp://localhost:1099
           
          注意:要正確運行示例程序,請啟動jboss,并將jboss的jbossall-client.jar文件放入classpath中。
           
          上述示例程序在jboss服務器的jndi樹上建立了幾個上下文,并bind了幾對象,大家可通過附錄中的代碼或其它工具查看
          查看結果為:
          -----------------------------
          /sylilzy/sily
          -----------------------------
          /sylilzy/sily/b:I am sily b!
          /sylilzy/sily/a:I am sily a!
          /sylilzy/sily/g1:this is g
          -----------------------------
          -----------------------------
           
          上述程序中,我們的代碼只涉及到了jndi API,其它細節如初始化jboss jndi的初始上下文,建立網絡連接,與服務器通信,對我們來說都是透明的,另外,我們將jboss jndi的spi包中的類名作為參數傳入了程序中,要訪問一個遠程對象,我們所做的就這么多。
           
          下面,再提供一個例子,與上例不同,我們不需要jboss,我們使用sun的FSSP(File System Service Provider)文件系統服務提供者.注意在這個例子中要使用到前面所說的File System Service Provider for the Java Naming and Directory InterfaceTM (JNDI)相關類(下載)。
          /*
           * Created on 2005-3-1
           *
           * To change the template for this generated file go to
           * Window>Preferences>Java>Code Generation>Code and Comments
           */
          package com.sily.jndi;
          import java.io.FileInputStream;
          import java.util.Properties;
          import javax.naming.*;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          /**
           * @author shizy
           *
           * To change the template for this generated type comment go to
           * Window>Preferences>Java>Code Generation>Code and Comments
           */
          public class JndiTest1 {
          	/**
          	 * 
          	 */
          	public JndiTest1() {
          		super();
          		// TODO Auto-generated constructor stub
          	}
          	public static void main(String[] args) {
          		try {
          			Properties env = new Properties();
          			env.load(new FileInputStream("fileSystemService.properties"));
          			env.put(Context.PROVIDER_URL, "file:///c:/");
          			Context ctx = new InitialContext(env);
          			ctx.createSubcontext("sylilzy");
          			
          			NamingEnumeration list = ctx.list("/");
          			while (list.hasMore()) {
          				NameClassPair nc = (NameClassPair) list.next();
          				System.out.println(nc);
          			}
          			
          		}
          		catch (Exception e) {
          			e.printStackTrace();
          		}
          	}
          }
          
           
          上例中fileSystemService.properties文件的內容為:java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
           
          這個例子較簡單,運行后,它會列出C:\下所有的文件和目錄,另外你會發現有一個新目錄被創建了.本例不同于上例,它并不需要服務端,因為它訪問的是文件系統.有關幫助可查閱包內的相關文檔。
           
          通過對比這兩個例子,應該JNDI的工作原理有了一個大致的了解。
          總結:
          jndi技術體現了分布式應用的優點,同進它的產生也為分布式對象提供了統一的訪問接口。由于篇幅所限,對目錄的操作本文未作介紹,其它內容將在接下來的系列中討論。要對JNDI技術作全面的了解,請參閱參考資料.要對于JNDI技術深入學習,仍有許多地方值得進一步了解,例如EJB容器所使用的JNDI所提供的對象就有 Local和Remote之分,對于Local Object,對于不同的JVM是不可訪問的;對于遠程對象的訪問,還涉及到Java安全機制。
           
          附錄:
          查看jboss jndi內容的代碼:
          //----------------------------------------
          /*
           * Created on 2005-3-4
           *
           * To change the template for this generated file go to
           * Window>Preferences>Java>Code Generation>Code and Comments
           */
          package com.sily.jndi;
          import java.io.FileInputStream;
          import java.util.Properties;
          
          import javax.naming.*;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          /**
           * @author shizy
           *
           * To change the template for this generated type comment go to
           * Window>Preferences>Java>Code Generation>Code and Comments
           */
          public class ListJbossJndi {
          	/**
          	 * 
          	 */
          	public ListJbossJndi() {
          		super();
          		// TODO Auto-generated constructor stub
          	}
          	public static void main(String[] args) {
          		try {
          			Properties env = new Properties();
          			env.load(new FileInputStream("jbossJndi.properties"));
          			//env.list(System.out);
          			Context ctx = new InitialContext(env);
          			listCtx(ctx.lookup("sylilzy"));
          		}
          		catch (Exception e) {
          			e.printStackTrace();
          		}
          	}
          	static void listCtx(Object o){
          		if(!(o instanceof Context))log(":"+o);
          		else {
          			log("\n-----------------------------");
          		try {
          			Context ctx=(Context)o;
          			//log(ctx.getNameInNamespace()+"/:");
          			NamingEnumeration list=ctx.listBindings("");
          			while(list.hasMore()){
          				Binding bind=(Binding)list.next();
          				log("\n/"+ctx.getNameInNamespace()+"/"+bind.getName());
          				listCtx(bind.getObject());
          			}
          			log("\n-----------------------------");
          		}
          		catch (NamingException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          	}
          	static void log(Object o){
          		System.out.print(o);
          	}
          }
          
          
              
           

          作者簡介:
              施祖陽,網名sylilzy,1979年生。
              2002年起從事軟件開發工作,主要研究為JAVA、Linux及相關技術。
              你可通過sylilzy@163.com與作者聯系。
           
          參考資料:
          1.http://java.sun.com/products/jndi/tutorial/
           
          posted on 2005-12-19 18:04 sylilzy 閱讀(317) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 博客| 林西县| 青铜峡市| 伊川县| 寻乌县| 张家港市| 兴隆县| 齐河县| 抚顺县| 孝昌县| 五峰| 张家港市| 江阴市| 肥城市| 河间市| 乐都县| 淄博市| 信宜市| 安吉县| 丹东市| 河间市| 安国市| 佛学| 华阴市| 项城市| 齐河县| 石河子市| 巴林右旗| 密云县| 百色市| 南平市| 维西| 郸城县| 仲巴县| 营口市| 抚远县| 武汉市| 盐亭县| 洛南县| 固阳县| 鸡泽县|