Connector框架筆記

一個ResourceAdapter能夠提供不一樣類型的Connection:java

  • Outbound communication(由JavaEE應用服務器建立到EIS的鏈接):
  • Inbound communication(由EIS建立到JavaEE應用服務器的鏈接):
  • Bi-directional communication(雙工通訊鏈接):

 

鏈接器框架定義了下面幾個應用服務器與EIS之間的接口:sql

  • Connection Management 鏈接管理接口(鏈接管理,鏈接池)
  • Transaction Management 事務管理接口(能夠將鏈接歸入應用服務器的TransactionManager的管理範圍)
  • Security Contract安全接口
  • ResourceAdapter Lifecycle Management Constract ResourceAdapter生命週期管理
  • Work Management Constract 任務管理接口,ResourceAdapter能夠向像線程池同樣向任務管理接口提交任務,用於處理Inbound Connection等。
  • 任務管理接口,ResourceAdapter能夠管理本身管理的任務。
  • 入站處理事務。(在事務上下文中處理Inbound Connection時)
  • 安全上下文。(在安全上下文中運行提交的Work任務)
  • 入站Message處理接口,ResourceAdapter能夠異步將消息傳遞給Message Endpoint進行處理,消息能夠是任何類型,而沒必要特定於jms(topic/queue)或者JAXM。

ResourceAdapter能夠提供一套EIS-Specific的Client API數據庫

鏈接器框架支持在非受管環境下運行。緩存

 

生命週期管理:安全

生命週期管理涉及的類以下圖所示:服務器

package javax.resource.spi;
import javax.resource.spi.work.WorkManager;
public interface ResourceAdapter { 
    void start(BootstrapContext) // startup notification
        throws ResourceAdapterInternalException;
    void stop(); // shutdown notification
        ... // other operations
}

public interface BootstrapContext { WorkManager getWorkManager(); ... // other operations }

 

ResourceAdatpter以及ResourceAdapter的啓動。網絡

ResourceAdapter:架構

  1. ResourceAdapter實現類由部署描述符或者@Connector註解來指定,
  2. ResourceAdapter實現類必須是一個JavaBean,部署的時候Deployer須要對它配置並設置相應的屬性。而且應用服務器可使用Validator來對它進行驗證。

ResourceAdapter的啓動過程:app

一、應用服務器實例化ResourceAdapter,並根據部署描述符設置相應的屬性。(每次部署只容許實例化一個ResourceAdapter對象)框架

二、應用服務器調用ResourceAdapter的start方法,在參數中傳入BootstrapContext對象,BootstrapContext對象向ResourceAdapter暴露應用服務器的組件服務好比WorkManager,ResourceAdapter可使用這些組件。

 

ResourceAdapter在start方法中須要作下面的工做:

一些ResourceAdapter的初始化工做,由於咱們的部署器只能給它設置相應的屬性,初始化工做由ResourceAdapter在start方法中去作。初始化工做涉及

建立ResourceAdapter相關的對象

建立線程(Work Management)

初始化Endpoint(好比到EIS的鏈接或者監聽端口)

 

在ResourceAdapter生命週期當中,ResourceAdapter能夠包含一些屢次建立或者銷燬的對象,好比ManagedConnectionFactory,ActivationSpec,以及各類Connection,一些私有的對象以及一些暴露給應用的ResourceAdapter相關的對象。

ManagedConnectionFactory用於建立到EIS的Outbound Connection,一個ResourceAdapter能夠有多個ManagedConnectionFactory對象。

ActivationSpec用於接收EIS的Inbound Connection,一個ResourceAdapter能夠有多個ActionvationSpec對象。

 

ManagedConnectionFactory

當ManagedConnectionFactory建立的時候,它能夠繼承一些ResourceAdapter的配置,並覆蓋一些默認的配置參數。

Output Communication由應用來發起而且與EIS通訊的過程在應用的上下文中執行,ResourceAdapter也能夠另起一個線程來處理通訊過程。

在使用ManagedConnectionFactory以前,應用服務器必須將它與ResourceAdapter實例關聯起來(經過調用ManagedConnectionFactory.setResourceAdapter方法)ManagedConnectionFactory.setResourceAdapter方法只容許調用一次,而且在ManagedConnectionFactory 的生命週期當中不能改變這個關聯關係。

 

ActivationSpec

同ManagedConnectionFactory相似,在初始化的時候,ActivationSpec也能夠繼承來自ResourceAdapter的配置。

Inbound communication由EIS來發起,通訊過程在ResourceAdapter線程上下文中執行,沒有應用的線程參與、Resource Adapter可使用Work Management contract接口來申請線程來處理Inbound Communication。

同ManagedConnectionFactory相似,使用ActivationSpec時,應用服務器必須將它與ResourceAdapter關聯,ActivationSpec生命週期過程當中不容許改變這個關聯關係。

 

ResourceAdapter中止過程

ResourceAdapter的中止分爲兩個階段:

階段一:

在中止Resource以前(調用ResourceAdapter的stop方法),應用服務器必須保證全部使用此ResourceAdapter資源的相關應用都已經中止,包括中止Message endpoints。階段一用於保證應用純再也不會使用到ResourceAdapter實例,這意味着全部相關應用的話動和事務活動都已經完成。所以階段一保證了即便下一階段中Resource Adapter不能正常中止,ResourceAdapter也再也不會被使用。

 

階段二:

應用服務器調用ResourceAdapter的stop方法,ResourceAdapter將在stop方法中執行中止操做以便被卸載。中止的操做包括如下幾個方面:

一、關閉網絡端口(Outbound and Inbound)

二、釋放線程以及活動的Work任務。

三、容許ResourceAdapter內部正在 處理的事務完成提交,並將緩存的數據刷出到EIS中。

stop方法拋出任何異常都不會阻止應用服務器銷燬ResourceAdapter

 

鏈接管理架構。

應用服務從部署描述符和註解中獲取配置信息來配置ResourceAdapter實例,ResourceAdapter提供Connection和ConnectionFactory。好比javax.sql.DataSource和java.sql.Connection接口針對關係數據庫提供的JDBC-base的接口。

相應地,CCI(Common Client Interface) 定義了javax.resource.cci.ConnectionFactory和javax.resource.cci.Connection。

應用組件經過jndi中的lookup操做來獲取一個 Connection Factory,並經過這個Connection Factory獲取一個鏈接到EIS的Connection實例。Connection Factory將connection 的建立請求委託給ConnectionManager來處理 。

應用服務器經過ConnectionManager來給受管應用提供QOS(quality-of-service),這裏的quality-of-services包括:

  1. 事務管理
  2. 安全
  3. 錯誤日誌記錄及跟蹤
  4. 鏈接池管理

應用服務器服用本身的實現方式去提供這些服務,鏈接器框架不指定應用服務器如何實現這些服務。

ConnectionManager實例接收到從Connection Factory過來的 Connection建立請求時,它從jndi上去獲取應用服務器提供的鏈接池資源,若是鏈接池壁上沒有可以知足相應請求的鏈接的話,應用服務器使用ManagedConnectionFactory接口(由ResourceAdapter來實現)來建立一個新的鏈接到EIS的物理鏈接。並將它加入到這個鏈接池當中。

應用服務器在ManagedConnection實例中註冊一個ConnectionEventListener,這使用應用服務器能夠從事件通知中獲取到ManagedConnection實例的狀態信息,進而利用這些事件通知去管理Connection Pooling(將鏈接加入池),管理事務,鏈接清理,以及處理一些錯誤。

應用服務器使用ManagedConnection實例去一個Connection實例,將它做爲應用層到物理Connection的Handle(代理)。好比javax.resource.cci.Connection就是這樣一個應用層的Connection Handler。

ResourceAdapter經過實現XAResource接口來提供事務管理,事務管理器也能夠實現LocalTransaction接口,使得應用服務器能夠管理ResourceManager內部的事務。

 

應用層面編碼模型

受管應用應用:

應用集成者(Application Assembler)或者組件提供者經過部署描述符來指定須要引用的Connection Factory

■ res-ref-name: eis/MyEIS 
■ res-type: javax.resource.cci.ConnectionFactory 
■ res-auth: Application or Container 
<resource-ref>
  <res-ref-name>connectionFactory/testConnectionFactory</res-ref-name>
  <res-ref-type>javax.sql.DataSource</res-ref-type>
  <res-auth>Container</res-auth>
</resource-ref>

在ResourceAdapter部署過程當中,deployer設置 ResourceAdapter的配置信息好比EIS的host, port等,而後應用服務器使用一個配置好的ResourceAdapter去建立到EIS的物理鏈接,

應用組件經過jndi獲取ConnectionFactory,好比:

// obtain the initial JNDI Naming context
Context initctx = new InitialContext();
// perform JNDI lookup to obtain the connection factory
javax.resource.cci.ConnectionFactory cxf = 
(javax.resource.cci.ConnectionFactory)
initctx.lookup(「java:comp/env/connectionFactory/testConnectionFactory」);

應用組件調用 Connection Factory的getConnection方法獲取一個到EIS的鏈接javax.resource.cci.Connection

應用組件經過獲取到的Connection實例對EIS進行操做。

操做完以後調用Connection實例的close方法。

 

鏈接管理涉及的接口/類UML圖以下:

 

ConnectionFactory和Connection

ConnectionFactory用於獲取到EIS實例的鏈接,Connection表示一個到EIS的鏈接。

public interface javax.resource.cci.ConnectionFactory 
        extends java.io.Serializable, javax.resource.Referenceable {
public javax.resource.cci.Connection getConnection() 
        throws javax.resource.ResourceException;
    ...
}
public interface javax.resource.cci.Connection {
    public void close() throws javax.resource.ResourceException;
    ...
}    

ResourceAdapter被容許在Connection Factory接口額外的getConnection方法。

Connection的接口中應該有一個close方法。

ResourceAdapter必須提供Connection Factory的Connection接口的實現

ConnectionFactory的實現必須在應用組件的線程中去調用ConnectionManager.allocateConnection方法。

public interface javax.resource.spi.ConnectionManager 
    extends java.io.Serializable {
    public Object allocateConnection(
        ManagedConnectionFactory mcf,
        ConnectionRequestInfo cxRequestInfo) 
            throws ResourceException;
}

public interface javax.resource.spi.ConnectionRequestInfo {
    public boolean equals(Object other);
    public int hashCode();
}

 

ConnectionRequestInfo

ConnectionRequestInfo對象使得在ConnectionManager.allocateConnection時能夠傳遞ResourceAdapter中的相關配置,資源甜酸器能夠繼承ConnectionRequestInfo來支持自定義的鏈接請求。

ManagedConnectionFactory必須持有所有用於建立物理鏈接的配置信息,這使得ConnectionManager能夠管理這些鏈接。

資源適配器(Resource Adapter)必須實現ConnectionRequestInfo接口中的equals方法和hashCode方法。

 

ConnectionManager

javax.resource.spi.ConnectionManager接口爲Resource Adapter嚮應用服務器傳遞鏈接建立請求提供了一個hook。allocateConnection方法由Connection Factory實例來調用,由些將建立請求傳遞給應用服務器的ConnectionManager實例。

public interface javax.resource.spi.ConnectionManager 
    extends java.io.Serializable {

    public Object allocateConnection(
            ManagedConnectionFactory mcf,
            ConnectionRequestInfo cxRequestInfo) 
                throws ResourceException;
}

應用服務器必須提供ConnectionManager的實現,而且這個實現不能特定到某個Resource Adapter。ConnectionManager的將委託給應用服務器的部署機制,由些來提供好比安全,鏈接池管理,事務管理以及錯誤日誌服務等。

ConnectionManager介入以後,鏈接建立請求被委託給ManagedConnectionFactory來進行處理,ManagedConnectionFactory將決定建立新請求仍是從已經有的鏈接中取出一個返回。ConnectionManager必須實現Serializable接口。

Resource Adapter也能夠提供一個ConnectionManager默認實現,用於非應用服務器管理的場合。

 

ManagedConnectionFactory

javax.resource.spi.ManagedConnectionFactory實現是ManagedConnection和Connection Factory的工廠類:

public interface javax.resource.spi.ManagedConnectionFactory 
    extends java.io.Serializable {
    public Object createConnectionFactory(
        ConnectionManager connectionManager)
        throws ResourceException;
    public Object createConnectionFactory()
        throws ResourceException;
    public ManagedConnection createManagedConnection(
        javax.security.auth.Subject subject, 
        ConnectionRequestInfo cxRequestInfo) 
        throws ResourceException;
    public ManagedConnection matchManagedConnections(
        java.util.Set connectionSet,
        javax.security.auth.Subject subject, 
        ConnectionRequestInfo cxRequestInfo) 
    throws ResourceException;
    public boolean equals(Object other);
        public int hashCode();
    }

createConnectionFactory方法用於建立Connection Factory實例,對於CCI來講,它就是javax.resource.cci.ConnectionFactory,而後使用應用服務器提供的ConnectionManager實例來對Connection Factory實例進行初始化。

createConnection方法用於建立一個物理鏈接。

matchConnection方法用於應用服務器從池中匹配一個鏈接。若是不能從池中匹配一個鏈接的話,這個方法直接返回null,而後應用服務器將請求Resource Adapter建立一個新的鏈接(上面的createConnection方法)

若是Resource Adapter不支持鏈接池的話,matchConnection方法它能夠直接拋出NotSupportedException,這樣子應用服務器就不會去緩存鏈接了。

ManagedConnectionFactory的實現類能夠實現ValidatingManagedConnectionFactory接口,應用服務器可使用該接口從池中移除無效的鏈接。

 

ManagedConnection

ManagedConnection實例表示一個物理鏈接,

public interface javax.resource.spi.ManagedConnection {
    public Object getConnection(
        javax.security.auth.Subject subject, 
        ConnectionRequestInfo cxRequestInfo) 
            throws ResourceException;
    public void destroy() throws ResourceException;

    public void cleanup() throws ResourceException;

    // Methods for Connection and transaction event notifications
    public void addConnectionEventListener(ConnectionEventListener listener);

    public void removeConnectionEventListener(ConnectionEventListener listener);

    public ManagedConnectionMetaData getMetaData()  throws ResourceException;

    // Additional methods - specified in the other sections
    ...
}

其中getConnection方法用於建立一個應用層面使用的Connection代理,對於CCI來講類型爲javax.resource.cci.Connection

ManagedConnection實例可使用getConnection方法並傳遞Subject和ConnectionRequestInfo參數來改變物理鏈接的狀態。

addConnectionEventListener方法容許往ManagedConnection裏面註冊事件監聽器,用於接收close/rrror或者事務相關的事件。

相反removeConnectionEventListener用於移除一個事件監聽器。

 

Inbound Communication

這裏涉及消息從EIS經過Resource Adapter投遞到應用的EJB Container的整個過程。這裏涉及到3個階段:

一、Message Inflow

二、Ejb Invocation

三、Transaction Inflow

 

Message Inflow

Message Inflow定義了Resource Adapter異步地給應用中的endpoint傳遞Message的通用接口,這使得標準的Message Provider能夠經過接入JavaEE應用服務器當中。這裏的Endpoint是指Message Endpoint,好比MDB

 

 

ResourceAdapter接口提供了啓用endpoint和禁用endpoint的方法,當須要啓動一個Message Endpoint時候,應用服務器調用endpointActivation方法,當須要禁用一個endpoint時候,應用服務器去調用endpointDeactivation方法。

調用endpointActivation/endpointDeactivation方法時,應用服務器傳遞一個MessageEndpointFactory的實例和一個配置好的ActivationSpec實例。

ResourceAdapter使用MessageEndpointFactory實例來獲取message endpoint實例,而後給把消息傳遞給它。可使用MessageEndpointFactory來獲取任意數量的message endpoint實例。

一個能夠向message endpoint傳遞消息的ResourceAdapter必須爲ActivationSpec提供它所支持的endpoint message listener類型(經過@Activation註解的messageListeners字段或者部署描述符<messagelistener-type>)。ActivationSpec實例是由message endpoint/application/deployer來配置,併爲endpoint activation設置必要的屬性配置信息。而後在endpoint部署的時候由應用服務器將ActivationSpec實例傳遞給resource adapter。

ResourceAdapter負責檢測endpoint message listener的類型(經過使用ActivationSpec JavaBean的信息或者ActivationSpec JavaBean的類型,而後將從EIS接收到的message傳遞給這個endpoint),當建立一個「事務的」message的時,Resource Adapter能夠選擇傳遞一個XAResource實例給message endpoint。

endpoint的生命週期以下 :

一、Endpoint deployment

二、Message delivery(transacted and non-transacted)

三、Endpoint undeployment

 

Endpoint Deployment

Endpoint一般是一個message-driven bean應用。

MessageEndpoint負責提供它監聽消息的類型(部署描述符<messaging-type>或者@MessageDriven的messageListeners字段)activation的配置信息(部署描述符<activation-config>或者@MessageDriven中的activationConfig字段)。

Resource adapter負責提供它支持的message listener類型,(message listener 接口的java全限定名)(resource adapter支持的message listener類型能夠經過@Activation註解的messageListeners字段配置或者部署描述符<messagelistener-type>)。

好比下面的部署描述符中的例子:

CODE EXAMPLE 13-3  Message-Driven Bean Deployment Descriptor
<!-- message-driven bean deployment descriptor -->
...
<message-driven>
    <ejb-name>ExpenseProcessing</ejb-name>
    <ejb-class>com.wombat.empl.ExpenseProcessingBean</ejb-class>
    <messaging-type>javax.jms.MessageListener</messaging-type>
...
<activation-config> <activation-config-property> <activation-config-property-name> destinationType </activation-config-property-name> <activation-config-property-value> javax.jms.Topic </activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name> SubscriptionDurability </activation-config-property-name> <activation-config-property-value> Durable </activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name> MessageSelector </activation-config-property-name> <activation-config-property-value> JMSType = 'car' AND color = 'blue' </activation-config-property-value> </activation-config-property> ... </activation-config>
</message-driven>
...

 

Application Server

應用服務器爲message endpoint提供運行時環境。

應用服務器必須在啓動應用組件的時候,將應用組件的ENC傳遞給resource adapter,resource adapter能夠在endpointActivation和endpointDeactivation方便裏面使用JNDI來獲取jndi上面的資源。

resource adapter使用ManagedEndpointFactory來建立Message Endpoint實例來將消息傳遞給它。

應用服務器須要將配置好的Administrered object綁定到java:comp/env底下 。

 

 

部署:

Resource Adapter Provider

Resource Adapter  提供者負責指定ResourceAdapter的部署描述符,提供者能夠在部署描述符中提供下面的信息

一、General information,一般是一些可讀信息,好比Resource Adapter的名字,描述,License和版本信息等等 。

二、依賴的WorkContext類,ResourceAdapter能夠提供一系列require-work-context元素用於指定要求應用服務器支持的WorkContext類型,這些類型必須是WorkContext的子類或者子接口。

三、javax.resource.spi.ResourceAdapter實現類,

四、ResourceAdapter的配置屬性信息,這些信息用於配置ResourceAdapter JavaBean的屬性。

五、Oubound resource adapter information

ManagedConnectionFactory實現類,與ResourceAdapter相同,它是遵循JavaBean規範。

ConnectionFactory接口和實現類

Connection接口及實現類。

Transaction Support事務支持狀況(針對ResourceAdapter的實現狀況),NoTransaction, LocalTransaction或者XATransaction。

ManagedConnectionFactory的默認配置信息(ManagedConnectionFactory能夠有多個實例)

Authentication Mechanism認證機制。BasicPassword/Kerbv5

Reauthentication support

Extended Security Permission

 

六、Inbound Resource Adapter Informcation

Message Listener Type:Resource Adapter提供者必須指定一個或者多個支持的Message Listener類型(應用服務器根據@MessageDriven註解上messageListeners字段或者<messsaging-type>描述符元素對Inbound Resource Adapter進行匹配)。

ActivationSpec類:Resource Adapter提供者改組指定ActivationSpec的實現類名,和ResourceAdapter同樣它也必須遵循JavaBean規範,ActivationSpec在部署過程當中由message endpoint deployer來進行配置。

ActivationSpec要求的屬性配置信息:

Administered object:Resource adapter提供者改必須指定Administered object的實現類 或者接口(應用服務器將查找接口的實現做爲Administered Object),和ResourceAdapter實現類同樣,必須遵循JavaBean規範,

 

Resource Definition Annotation

@ConnectionFactoryDefinition和@AdministeredObjectDefinition註解用於協助應用開 者定義和配置運行時要求的Resource Adapter相關資源。這些註解經過name來引用resource adapter。若是resource adapter打包在ear應用中的話,resource adapter的名字以#號開頭,表示引用ear應用裏面的resource adapter。

@ConnectionFactoryDefinition是一種Resource Definition Annotation,等同於<connection-factory>部署描述符元素,它用於定義一個connection factory並將它註冊在jndi上,這個東西相似咱們的@Resource/@PersistenceUnit等,這是JavaEE7引進來的annotation,相似於@DataSourceDefinition。在JavaEE7以前,ConnectionFactory只能經過私有部署描述符的方式建立 。

package javax.resource; 
import java.lang.annotation.Target; 
import java.lang.annotation.Retention; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.RetentionPolicy; 

@Documented
@Target({ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ConnectionFactoryDefinition { 
    String name(); 
    String description() default ""; 
    String resourceAdapter(); 
    String interfaceName();
    TransactionSupport.TransactionSupportLevel transactionSupport() default TransactionSupport.TransactionSupportLevel.NoTransaction; 
    int maxPoolSize() default -1; 
    int minPoolSize() default -1; 
    String[] properties() default {}; 
} 

resourceAdapter字段用於指定resource adapter的名字()

interfaceName字段用於指定connection factory的全限定類名(必填),應用服務器將用它來查找對應的RAR中的ManagedConnectionFactory

@ConnectionFactoryDefinition(name="java:comp/eis/MyEISCF",
 interfaceName="com.eis.ConnectionFactory",
 resourceAdapter="MyEISRA",
 transactionSupport=
TransactionSupport.TransactionSupportLevel.XATransaction)
@Stateless
public class TestBean {
    ....
}
相關文章
相關標籤/搜索