天天看點

jndi+SPI和API

SPI和API

api的意義,其實就是這些提供給你完成某項功能的類、接口或者方法。

而SPI(Service Provider Interface)是指一些提供給你繼承、擴充,完成自定義功能的類、接口或者方法。

SPI是一種回調的思想,回調是指我們在使用api時,我們可以向api傳入一個類或者方法,api在合适的時間調用類或者方法。

SPI是在一些通用的标準中,為标準的實作産商提供的擴充點。

标準在上層提供API,API内部使用了SPI,當API被客戶使用時,會動态得從目前運作的classpath中尋找該SPI的實作,然後使用該SPI的實作來完成API的功能。

SPI的實作方式是:提供實作的實作類打包成Jar檔案,這個Jar檔案裡面必須有META-INF目錄,其下又有services目錄,其下有一個文本檔案,檔案名即為SPI接口的全名,檔案的内容該jar包中提供的SPI接口的實作類名。

舉一個著名的例子:

mysql的驅動包提供了java.sql.Driver這個SPI的實作,實作類是com.mysql.jdbc.Driver,在mysql-connector-java-5.1.6.jar中,我們可以看到有一個META-INF/services目錄,目錄下有一個檔案名為java.sql.Driver的檔案,其中的内容是com.mysql.jdbc.Driver。

在運作DriverManager.getDriver并傳入參數“com.mysql.jdbc.Driver”時,DriverManager會從mysql-connector-java-5.1.6.jar中找到com.mysql.jdbc.Driver并執行個體化傳回一個com.mysql.jdbc.Driver的執行個體。

jndi

jndi是Java 命名和目錄接口(Java Naming and Directory Interface,JNDI)的簡稱.

從一開始就一直是 Java 2平台企業版的核心技術之一。在JMS,JMail,JDBC,EJB等技術中,就大量應用的這種技術。

JNDI可通路的現有的目錄及服務有:DNS、XNam 、Novell目錄服務、LDAP(Lightweight Directory Access Protocol 輕型目錄通路協定)、 CORBA對象服務、檔案系統、Windows XP/2000/NT/Me/9x的系統資料庫、RMI、DSML v1&v2、NIS。

JNDI的架構與JDBC的架構非常類似.JNDI架構提供了一組标準命名系統的API,這些API在JDK1.3之前是作為一個單獨的擴充包

jndi.jar(通過這個位址下載下傳),這個基礎API建構在與SPI之上。這個API提供如下五個包

 javax.naming

 javax.naming.directory

 javax.naming.event

 javax.naming.ldap

 javax.naming.spi

 在應用程式中,我們實際上隻使到用以上幾個包的中類.具體調用類及通信過程對使用者來說是透明的.JNDI API提供了通路不同JNDI服務的一個标準的統一的實作,其具體實作可由不同的 ServiceProvider來完成。前面講的為第一層JNDI API層.最下層為JNDI SPI API及其具體實作。

它包括了幾個增強和下面的命名/目錄服務提供者:

 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 SDK1.3及以上的版本中已經包括。

前面講解的隻是作為應用程式用戶端的架構實作,其服務端是由SPI對應的公司/廠商來實作的,我們隻需将服務端的相關參數傳給JNDI

API就可以了,具體調用過程由SPI來完成。

典型的運用場景:資料源

tomcat中配置一個資料源,程式就可以通過java.sql接口去通路資料庫,不管底層的資料庫是什麼類型。

命名服務主要API javax.naming

1、Context接口和InitialContext類

Context是命名服務的核心接口,提供對象查找,綁定/解除綁定,重命名對象,建立和銷毀子上下文等操作。

InitialContext類實作了Context接口,是通路命名服務的起始上下文,通過它可查找對象和子上下文。

Context主要方法:

Object lookup(Name name)

Object lookup(String name)

根據名稱擷取對象

void bind(Name name, Object obj)

void bind(String name, Object obj)

綁定名稱到對象

void unbind(Name name)

void unbind(String name)

解除綁定,釋放對象

void rebind(Name name, Object obj)

void rebind(String name, Object obj)

将對象和一個已經存在的名稱重新綁定

void rename(Name oldName, Name newName)

void rename(String oldName, String newName)

修改對象名稱

NamingEnumeration<NameClassPair>list(Name name)

NamingEnumeration<NameClassPair>list(String name)

列出上下文中的所有對象名稱資訊。NameClassPair包含對象名稱和對象類名。

NamingEnumeration<Binding>listBindings(Name name)

NamingEnumeration<Binding>listBindings(String name)

列出上下文中的所有綁定。

Context createSubcontext(Name name)

Context createSubcontext(String name)

建立子上下文

void destroySubcontext(Name name)

void destroySubcontext(String name)

銷毀子上下文

2、Name接口

對應于命名服務概念中的對象名稱。它的具體實作可能是一個簡單的字元串,也可能是一個複雜對象。CompoundName類和CompositeName類均實作了Name接口,分别代表複合名稱和混合名稱。

3、Binding類

對應于命名服務概念中的綁定。一個Binding包含對象名稱,對象的類名稱,對象本身。

Binding主要方法:

String getName()

void setName(String name)

擷取/設定對象名稱

String getClassName()

setClassName(String name)

擷取/設定對象類名

Object getObject()

void setObject(Object obj)

擷取/設定對象

4、Referenceable接口和Reference類

命名服務中對象的存儲方式各不相同。有的将對象直接序列化,這時實作标準的Serializable接口接口。有的要将對象存儲在命名系統外部,這就要用到Referenceable接口和Reference類了。Reference類包含了怎樣構造出一個實際對象的資訊,實際對象則需要實作Referenceable接口。

Referenceable主要方法:

Reference getReference() 傳回對象的引用。

當将一個實作了Referenceable接口的對象綁定到Context時,實際上通過getReference()得到它的Reference進行綁定。而如何從Reference中建立出Referenceable執行個體,則由具體的SPI實作,JNDI客戶不用關心。

目錄服務主要APIjavax.naming.directory

1、DirContext接口和InitialDirContext類

DirContext是目錄服務的核心接口,它擴充了Context接口,除了提供了命名服務的各種操作外,還提供了通路和更新目錄對象屬性的操作,以及Search操作。

InitialDirContext類擴充InitialContext類并實作了DirContext接口,是通路目錄服務的起始點。

DirContext主要方法:

binding/rebing/unbinding等方法與Context類似,差別是各個方法中均添加了Attributes參數,表示綁定的是一個目錄對象,其中有對象本身,還有對象的屬性集合。這裡不再列舉。

Attributes getAttributes(Name name)

擷取對象的屬性集合

void modifyAttributes(Name name, int mod_op, Attributesattrs)

修改對象的屬性集合

NamingEnumeration<SearchResult>search(Name name, Attributes matchingAttributes)

搜尋包含比對的屬性的對象。

NamingEnumeration<SearchResult>search(Name name, String filter, SearchControls cons)

通過查詢過濾條件進行搜尋,同時指定了搜尋控制。

2、Attribute接口和Attributes接口

Attribute接口對應于目錄服務概念中的屬性。Attributes表示屬性的集合。

3、SearchResult類和SearchControls類

SearchResult類繼承自Binding類,表示DirContext的search操作的結果。SearchControls類用于對搜尋操作進行