91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JNDI在JavaEE中的角色_動力節點Java學院整理

發布時間:2020-08-20 21:21:32 來源:腳本之家 閱讀:138 作者:kirk 欄目:編程語言

雖然 J2EE 平臺提高了普通企業開發人員的生活水平,但是這種提高是以不得不學習許多規范和技術為代價的,這些規范和技術則是 J2EE 為了成為無所不包的分布式計算平臺而整合進來的。Dolly Developer 是眾多開發人員中的一員,她已經發現了一個特性,該特性有助于緩解隨企業級應用程序部署而帶來的負擔,這個特性就是 JNDI,即 Java 命名與目錄接口(Java Naming and Directory Interface)。讓我們來看看 Dolly 在沒有 JNDI 的時候是怎么做的,以及她是如何正確地應用 JNDI 來改善其狀況的。

所有人都非常熟悉的旅程

Dolly Developer 正在編寫使用 JDBC 數據源的 Web 應用程序。她知道自己正在使用 MySQL,所以她將一個對 MySQL JDBC 驅動程序類的引用進行了編碼,并通過使用適當的 JDBC URL 連接到其 Web 應用程序中的數據庫。她認識到數據庫連接池的重要性,所以她包含了一個連接池包,并把它配置成最多使用 64 個連接;她知道數據庫服務器已經被設置成最多允許 128 臺客戶機進行連接。

Dolly 在走向災難

在開發階段,每件事都進行得很順利。但是,在部署的時候,開始失控。Dolly 的網絡管理員告訴她,她不能從她的桌面機訪問生產服務器或登臺服務器(staging server),所以她不得不為每個部署階段開發不同的代碼版本。因為這種情況,她需要一個新的 JDBC URL,所以還要為測試、階段和生產進行獨立的部署。(一聽到要在每個環境中建立單獨部署,熟悉配置管理的人會戰戰兢兢的,但是既然這是種非常普遍的情況,所以他們也只好硬著頭皮上了。)

就在 Dolly 認為通過不同的 URL 建立彼此獨立的部署已經解決了自己的配置問題時,她發現她的數據庫管理員不想在生產環境中運行 MySQL 實例。他說,MySQL 用作開發還可以,但是對于任務關鍵型數據而言,業務標準是 DB2®。現在她的構建不僅在數據庫 URL 方面有所不同,而且還需要不同的驅動程序。

事情越變越糟。她的應用程序非常有用,并且變得非常關鍵,以致于它從應用服務器那里得到了故障恢復的能力,并被復制到 4 個服務器集群。但是數據庫管理員提出了抗議,因為她的應用程序的每個實例都要使用 64 個連接,而數據庫服務器總共只有 200 個可用連接 —— 全部都被 Dolly 的應用程序占用了。更麻煩的是,DBA 已經確定 Dolly 的應用程序只需要 32 個連接,而且每天只有一個小時在使用。隨著她的應用程序規模擴大,應用程序遇到了數據庫級的爭用問題,而她的惟一選擇就是改變集群的連接數量,而且還要做好準備,在集群數量增長或者應用程序復制到另一個集群時再重復一次這樣的操作。看來她已經決定了如何配置應用程序,應用程序的配置最好是留給系統管理員和數據庫管理員來做。

J2EE 的角色

如果 Dolly 在開發應用程序時了解 J2EE 所扮演的角色,那么她就可能避免遭遇這種困境。J2EE 規范把職責委托給多個開發角色:組件提供者(Component Provider)、應用程序組裝者(Application Assembler)、部署人員(Deployer)和系統管理員(System Administrator)。(在許多公司中,組件提供者和組件組裝者的角色是融合在一起的,部署人員和系統管理員的角色是融合在一起的。)在真正了解 J2EE 中的 JNDI 角色之前,掌握 J2EE 角色的作用非常重要。

組件提供者

這個角色負責創建 J2EE 組件,J2EE 組件可以是 Web 應用程序、企業級 JavaBean(EJB)組件,或者是應用程序客戶機(例如基于 Swing 的 GUI 客戶機應用程序)。組件提供者包括:HTML 設計師、文檔編程人員以及其他開發人員角色。大多數 J2EE 開發人員在組件提供者這一角色上耗費了相當多的時間。

應用程序組裝者

這個角色將多個 J2EE 模塊捆綁成一個彼此結合的、可以部署的整體:企業歸檔(EAR)文件。應用程序組裝者要選擇組件,分清它們之間的交互方式,配置它們的安全性和事務屬性,并把應用程序打包到 EAR 文件中。許多 IDE,例如 WebSphere® Studio、IDEA、JBuilder、WebLogic Workshop 和其他 IDE,都可以幫助應用程序組裝者以交互方式配置 EAR 文件。

部署人員(Deployer)

這個角色負責部署,這意味著將 EAR 安裝到 J2EE 容器(應用服務器)中,然后配置資源(例如數據庫連接池),把應用程序需要的資源綁定到應用服務器中的特定資源上,并啟動應用程序。

系統管理員(System Administrator)

這個角色負責保證容器需要的資源可用于容器。

角色實戰

假設有一個企業應用程序,該應用程序包含一個 Web 應用程序,還有一個負責業務邏輯和持久性的 EJB 組件。開發這個應用程序的組件供應商可能有許多,但是在許多情況下,可以由一個人來承擔全部職責。組件可以包含數據傳輸對象(一個 JAR 文件)、EJB 接口(另一個 JAR 文件)、EJB 實現本身(另一個 JAR 文件),以及用戶界面組件 —— servlet、JSP、HTML 頁面和其他靜態 Web 內容。用戶界面組件被進一步打包成 Web 應用程序,其中包含 servlet 類、JSP 文件、靜態內容,以及其他必需組件的 JAR(包括 EJB 接口)。

這聽起來好像用到的組件太多了,幾乎超出了人的想像范圍,尤其是在考慮構建一個典型的 Web 應用程序需要使用多少個 JAR 文件的時候。但是,重要的是認識到在這里必須小心地管理依賴性。接口和傳輸對象是 Web 應用程序和 EJB 實現可以依賴的對象,但是依賴性的方向應該是相同的;還要避免產生循環依賴。J2EE 組件(例如 WAR 文件和 EJB JAR 文件)必須在它們的部署單元之外聲明它們在資源上的依賴性。

應用程序組裝者負責把 Web 應用程序中的依賴內容包含進來,并把它們整體打包成單個企業應用程序。工具在這里幫助很大。IDE 可以協助創建反映模塊和 JAR 依賴性的項目結構,還允許您隨意指定包含或排除的模塊。

部署人員負責確保部署環境中存在組件所需的資源,并將組件綁定到平臺的可用資源上。例如,Web 應用程序中的外部 EJB 引用(部署描述符中的 ejb-ref)就是在此時被綁定到實際部署的 EJB 組件 —— 而且是立即綁定。

外部資源的后綁定

任何不平凡(nontrivial)的 J2EE 應用程序都需要訪問描述它期望使用環境的信息。這意味著開發和測試組件時,為了臨時測試代碼,開發人員要承擔一些部署方面的職責。重要的是要理解:這么做的時候,您就走出了開發人員的領域。否則,可以試著依靠 JDBC 驅動程序,或 URL、JMS 隊列名稱,或者其他具有無意識的、偶爾可能是災難性暗示的機器資源。

JNDI 前來援助

Dolly 的問題的解決方案是從她的應用程序中清除所有對數據存儲的直接引用。沒有對 JDBC 驅動程序的引用,沒有服務器名稱,沒有用戶名稱或口令 —— 甚至沒有數據庫池或連接管理。Dolly 需要編寫代碼來忽略將要訪問的特定外部資源,只需要知道其他人會提供使用這些外部資源所需的鏈接即可。這允許部署人員(任何處在這個角色的人)把數據庫連接分配給 Dolly 的應用程序。Dolly 沒有必要參與其中。(從數據庫安全性到遵守 Sarbanes-Oxley 法案,她都沒有參與進來,她這樣做也有充足的業務理由。)

許多開發人員知道:代碼和外部資源之間的緊密耦合是潛在的問題,但是在實踐中卻經常忘記角色的劃分。在小型開發工作中(指的是團隊規模或部署規模),即使忽視角色劃分也能獲得成功。(畢竟,如果應用程序只是個人的應用程序,而且您不準備依靠它,那么把應用程序鎖定在特定的 PostgreSQL 實例上也挺好的。)

J2EE 規范要求所有 J2EE 容器都要提供 JNDI 規范的實現。JNDI 在 J2EE 中的角色就是“交換機” —— J2EE 組件在運行時間接地查找其他組件、資源或服務的通用機制。在多數情況下,提供 JNDI 供應者的容器可以充當有限的數據存儲,這樣管理員就可以設置應用程序的執行屬性,并讓其他應用程序引用這些屬性(Java 管理擴展(Java Management Extensions,JMX)也可以用作這個目的)。JNDI 在 J2EE 應用程序中的主要角色就是提供間接層,這樣組件就可以發現所需要的資源,而不用了解這些間接性。

Dolly 的情況更糟了

現在我們重新來看一下 Dolly 的情況。在其簡單的 Web 應用程序中,她直接從應用程序代碼中使用了一個 JDBC 連接。參見清單 1,我們可以看出,Dolly 顯式地把 JDBC 驅動程序、數據庫 URL 以及她的用戶名和口令編碼到了 servlet 中:

清單 1. 典型(但是不好)的 JDBC 用法

Connection conn=null;
try {
 Class.forName("com.mysql.jdbc.Driver",
        true, Thread.currentThread().getContextClassLoader());
 conn=DriverManager.getConnection("jdbc:mysql://dbserver?user=dolly&password=dagger");
 /* use the connection here */
 c.close();
} 
catch(Exception e) {
 e.printStackTrace();
} 
finally {
 if(conn!=null) {
  try {
   conn.close();
  } catch(SQLException e) {}
 }
}

如果不用這種方式指定配置信息,Dolly(以及她的同伴們)使用 JNDI 來查找 JDBC DataSource 會更好一些,如清單 2 所示:

清單 2. 使用 JNDI 得到數據源

Connection conn=null;
try {
 Context ctx=new InitialContext();
 Object datasourceRef=ctx.lookup("java:comp/env/jdbc/mydatasource");
 DataSource ds=(Datasource)datasourceRef;
 Connection c=ds.getConnection();
 /* use the connection */
 c.close();
} 
catch(Exception e) {
 e.printStackTrace();
} 
finally {
 if(conn!=null) {
  try {
   conn.close();
  } catch(SQLException e) { }
 }
}

為了能夠得到 JDBC 連接,首先要執行一些小的部署配置,這樣我們才可以在本地組件的 JNDI 下文中查找 DataSource。這可能有點煩瑣,但是很容易學。不幸的是,這意味著即使是為了測試組件,開發人員也必須涉足部署人員的領地,并且還要準備配置應用服務器。

配置 JNDI 引用

為了讓 JNDI 解析 java:comp/env/jdbc/mydatasource 引用,部署人員必須把 <resource-ref> 標簽插入 web.xml 文件(Web 應用程序的部署描述符)。 <resource-ref> 標簽的意思就是“這個組件依賴于外部資源”。清單 3 顯示了一個示例:

清單 3. resource-ref 入口

<resource-ref>
 <description>Dollys DataSource</description>
 <res-ref-name>jdbc/mydatasource</res-ref-name>
 <res-ref-type>javax.sql.DataSource</res-ref-type>
 <res-auth>Container</res-auth>
</resource-ref>

<resource-ref> 入口告訴 servlet 容器,部署人員要在 組件命名上下文(component naming context) 中設置一個叫做jdbc/mydatasource 的資源。組件命名上下文由前綴 java:comp/env/ 表示,所以完全限定的本地資源名稱是:java:comp/env/jdbc/mydatasource.

這只定義了到外部資源的本地引用,還沒有創建引用指向的實際資源。(在 Java 語言中,類似的情況可能是: <resource-ref> 聲明了一個引用,比如 Object foo,但是沒有把 foo 設置成實際引用任何 Object。)

部署人員的工作就是創建 DataSource(或者是創建一個 Object 對象,讓 foo 指向它,在我們的 Java 語言示例中就是這樣)。每個容器都有自己設置數據源的機制。例如,在 JBoss 中,是利用服務來定義數據源(請參閱 $JBOSS/server/default/deploy/hsqldb-ds.xml,把它作為示例),它指定自己是 DataSource 的全局 JNDI 名稱(默認情況下是 DefaultDS)。在創建資源之后,第三步仍然很關鍵:把資源連接或者綁定到應用程序組件使用的本地名稱。在使用 Web 應用程序的情況下,是使用特定于供應商的部署描述符擴展來指定這個綁定,清單 4 中顯示了一個這樣的例子。(JBoss 用稱為 jboss-Web.xml 的文件作為特定于供應商的 Web 應用程序部署描述符。)

清單 4. 用特定于供應商的部署描述符將資源綁定到 JDI 名稱

<resource-ref>
  <res-ref-name>jdbc/mydatasource</res-ref-name>
  <jndi-name>java:DefaultDS</jndi-name>
</resource-ref>

這表明應該將本地資源引用名稱( jdbc/mydatasource)映射到名為 java:DefaultDS 的全局資源。如果全局資源名稱出于某種原因發生了變化,而應用程序的代碼無需變化,那么只需修改這個映射即可。在這里,有兩個級別的間接尋址:一個定義并命名資源(java:DefaultDS),另一個把特定于本地組件的名稱( jdbc/mydatasource)綁定到命名的資源。(實際上,當您在 EAR 級別上映射資源時,可能還存在第三級別的間接尋址。)

超越數據源

當然,J2EE 中的資源并不局限于 JDBC 數據源。引用的類型有很多,其中包括資源引用(已經討論過)、環境實體和 EJB 引用。特別是 EJB 引用,它暴露了 JNDI 在 J2EE 中的另外一項關鍵角色:查找其他應用程序組件。

試想一下這種情況:當一家公司從 Order Ontology Processing Services(OOPS)購買了一個可部署的 EJB 組件來處理客戶訂單時,會發生什么。為了便于舉例說明,我們把它叫做 ProcessOrders V1.0。ProcessOrders 1.0 有兩部分:一組接口和支持類(home 和 remote 接口,以及支持的傳輸類);實際 EJB 組件自身。選擇 OOPS 是因為它在這個領域的專業性。

該公司遵照 J2EE 規范,編寫使用 EJB 引用的 Web 應用程序。公司的部署人員把 ProcessOrders 1.0 綁定到 JNDI 樹中,將它用作ejb/ProcessOrders/1.0,并解析 Web 應用程序的資源名稱,以指向這個全局 JNDI 名稱。目前為止,這些都是 EJB 組件非常普通的用法。但是,當我們考慮公司的開發周期與公司供應商之間的交互時,事情就變得復雜起來。在這里,JNDI 也能幫助我們。

我們假設 OOPS 發布了一個新版本,即 ProcessOrders V1.1。這個新版本有一些新功能,公司內部的一個新應用程序需要這些新功能,而且很自然地擴展了 EJB 組件的業務接口。

在這里,公司有以下幾個選擇:可以更新所有應用程序來使用新版本,也可以編寫自己的版本,或者使用 JNDI 的引用解析,允許每個應用程序在不影響其他應用程序的情況下使用自己的 EJB 組件版本。立刻更新所有應用程序對維護來說是一場噩夢,它要求對所有組件都進行完整的回歸測試,這通常是一項艱巨的任務,而且如果發生任何功能測試失敗的話,那么還要進行另一輪調試。

編寫內部(in-house)組件常常是沒有必要的重復工作。如果組件是由在這個業務領域內具有專業知識的公司編寫的,那么給定的 IT 商店不可能像專業的組件供應商那樣精通業務功能。

正如您可能已經猜到的那樣,最好的解決方案是用 JNDI 解析。EJB 的 JNDI 引用非常類似于 JDBC 資源的引用。對于每個引用,部署人員都需要把新組件按特定的名稱(比如說 ejb/ProcessOrders/1.1)綁定到全局樹中,對于需要 EJB 組件的其他每個組件,還要為組件在部署描述符中解析 EJB 引用。依賴于 V1.0 以前的應用程序不需要進行任何修改,也不需要重新測試,這縮短了實現的時間、降低了成本并減少了復雜性。在服務趨于轉換的環境中,這是一種很有效的方法。可以對應用程序架構中所得到的所有組件進行這類配置管理,從 EJB 組件到 JMS 隊列和主題,再到簡單配置字符串或其他對象,這可以降低隨時間的推移服務變更所產生的維護成本,同時還可以簡化部署,減少集成工作。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴里| 花垣县| 黄浦区| 合阳县| 英超| 崇信县| 中西区| 南溪县| 景德镇市| 敦化市| 南和县| 衡阳市| 方正县| 井研县| 乌拉特中旗| 南阳市| 乌什县| 玉环县| 中方县| 皮山县| 太原市| 内江市| 彝良县| 宁陕县| 任丘市| 丰镇市| 朝阳市| 萝北县| 新巴尔虎左旗| 翼城县| 晴隆县| 德昌县| 吴旗县| 景洪市| 广水市| 政和县| 桃园市| 耒阳市| 永昌县| 泗水县| 徐水县|