一个ResourceAdapter能够提供不一样类型的Connection:java
链接器框架定义了下面几个应用服务器与EIS之间的接口:sql
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:架构
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包括:
应用服务器服用本身的实现方式去提供这些服务,链接器框架不指定应用服务器如何实现这些服务。
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 { .... }