2014-10-19 55 views
0

這不是一個真正的問題,但更多的是JCA專家的問題,讓我看到JCA規範的一個方面。 我想了解爲什麼JCA要求資源適配器bean和受管連接工廠必須實現equals()hashCode()爲什麼JCA要求在ResourceAdapter和ManagedConnectionFactory bean上等於&hashCode?

IMO資源適配器或受管連接工廠是由應用程序服務器管理的對象,至少在託管環境中。因此它們離EJB,Servlet和CDI託管的bean不遠,應用程序服務器負責管理實例。 並且資源適配器類或受管連接工廠類的實例數量由其部署直接定義。

那麼爲什麼有人需要這些類的equals()hashCode()? 我從來沒有做任何其他的實現,只是調用超級實現,直到現在,它工作得很好。 但是,當然聲納並不真的很欣賞這一點。

回答

0

如果你看一看規範,你會發現原因:https://jcp.org/aboutJava/communityprocess/mrel/jsr322/index.html

6.5.3.2要求 資源適配器必須提供的ManagedConnectionFactory接口的實現。 需要ManagedConnectionFactory實現類擴展hashCode的實現,並等於java.lang.Object中定義的方法。應用程序服務器使用這兩種方法以特定於實現的方式構建連接池。 equals和hashCode方法實現應該基於一組完整的配置屬性,這些配置屬性使得ManagedConnectionFactory實例對於EIS實例是唯一且特定的。

+0

嗨西蒙,謝謝你的迴應!我已經在規範中找到了這個段落,因爲大多數應用服務器都在錯誤消息中指明瞭該節號;-)我的問題更多地是關於規範要求的原因?我看不到在RA上使用這些方法的理由,這些方法對於EJB,CDI託管的bean等不具有同等效力。 – 2014-10-20 19:18:46

+0

資源適配器與EJB或CDI完全不同。由於JCA組件集中在App Server中。因此,如果App服務器將Factory保存在一個集合中,則使用equals和hashCode。 – 2014-10-20 19:27:37

+0

嗯......與RA不同,IMO的意見EJB相當集中。我通過我的部署直接定義了我的RA或MCF的實例數量,至少在託管環境中。我期望每個部署只創建和啓動一個RA,而不是每個都使用相同的屬性。也許這在非託管環境中更有意義。 – 2014-10-20 19:35:57

1

從JCA規範引用(1.0版本,但是1.5擁有相同的文字,我認爲新版本的一樣好):

資源適配器需要提供ManagedConnectionFactory接口的實現。
要求ManagedConnectionFactory實現類擴展java.lang.Object類中定義的hashCodeequals方法的實現。應用程序服務器使用這兩種方法以特定於實現的方式構建連接池。方法實現應該基於一組完整的配置屬性,這些配置屬性使得實例對於EIS實例而言是唯一的和特定的。

的應用服務器可以使用在其連接池管理中使用它的搜索和匹配的標準附加參數。這些參數可能是EIS或應用程序服務器特定的。在ManagedConnectionFactoryConnectionRequestInfo上定義的方法equalshashCode便於應用服務器進行連接池管理和結構化。

該規範沒有提供更多關於此內容的內容(除了對某些其他接口指定相同的要求外)。

由於總體思路是受管連接實現由供應商(例如數據庫供應商)提供,並且應用程序服務器可以彙集資源(例如ManagedConnection實例)和句子「這兩種方法均由一個應用服務器以實現特定的方式構建其連接池「我只能假設這樣做是爲了簡化實現的實現,例如用於HashMapHashSet等。例如,創建兩個具有相同屬性的ManagedConnectionFactory實例將具有equalshashCode的結果相同,因此可以使用相同的池。

這似乎是由以下引自同一個規格的支持:

應用服務器可以每ManagedConnectionFactory實例 (從而對每個EIS實例)的基礎上分區的游泳池。應用程序服務器可以選擇保證(以具體實現的方式),它總是至少按照實例粒度劃分連接池。

JCA規範似乎暗示到單個系統的連接應該由單個託管連接工廠處理(儘管我相信它沒有明確說明)。這需要一種方法根據其屬性找到一個單一的ManagedConnectionFactory。作爲一個例子,Jaybird(我維護的Firebird JDBC驅動程序)的核心是一個JCA實現(它可以是一個真正的痛苦)。 Jaybird的初始實現是由David Jencks撰寫的,他也編寫了JBoss的JCA實現。在驅動程序中equalshashCode以多種方式被使用:

  1. ManagedConnectionfactory保持靜態WeakHashMap指向一個實例本身。這用於規範化一個實例(如果實例已經存在與equalshashCode相同,則返回該實例)。
  2. java.sql.Driver實施org.firebirdsql.jdbc.FBDriver保持來自ManagedConnectionfactory一個WeakHashMap到一個(非池)javax.sql.DataSource實現。創建新連接時,會檢索(或以其他方式創建)此數據源以創建實際連接。
  3. 當一個ManagedConnectionFactory被反序列化時,readResolve方法將返回規範化版本(見1),如果它已經在映射中。

作爲便箋:感謝您提出這一點;它看起來像Jaybird中的當前實現有一個bug,因爲這兩個映射都保持對託管連接工廠的直接和間接的強引用,這使得使用較弱的哈希映射而無用。

+0

感謝您提供洞察真正的實現。您認爲應用程序服務器可能創建一個MCF部署的多個實例嗎?或者更糟的是,創建一個RA部署的多個實例並僅在一個實例上調用start()?甚至在所有情況下? (我不知道哪種方式會讓我更頭痛;-)) – 2014-10-20 20:41:40

+0

@RobertPanzer說實話,我並不熟悉JCA的所有要求(當我接管項目時,我繼承了當前的實現,而且我還沒有深入研究它)。據我所知,資源適配器只加載一次;我最好的猜測是,這也可能用於兩個RA指向相同資源的情況;並且如上所述查找與RA相關聯的池。 – 2014-10-20 20:49:27