- 浏览: 36692 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
linuxtyh:
asdfsd
Hessian android版(基于官方Hessian 4.07) -
tomatozq:
NoClassDefFoundError是因为lib库的jav ...
Hessian android版(基于官方Hessian 4.07) -
xieyulin2006:
哥们 ,您好 ,能把hessian-4.0.7-android ...
Hessian android版(基于官方Hessian 4.07) -
tony21st:
按楼主的方式,我对hessian4.07做相同的定制,仍然会在 ...
Hessian android版(基于官方Hessian 4.07) -
machismo:
太感谢了~ 赞一个
Hessian android版(基于官方Hessian 4.07)
Listeners, Routers/Notifiers and Actions
Listeners
Listerners封装了ESB-aware消息接收的端点。一旦接收到一个消息,一个listener会将消息传送进消息处理器管道,这个管道在将结果路由到“ReplyTo”端点之前会对消息进行处理。发生在管道中的动作处理可能包含以下步骤:在一个消息处理器中转换消息,在下一个处理器中应用业务逻辑。这些都是在处理结果路由到管道的下一个处理或者下个端点之前完成的。
注意:可以为listener配置许多参数,比如活动的线程数。更多设置请参照Defining Service Configuration。
Routers
Routers是ESB消息本身或者它的payload被路由到端点的方式。一些router支持“unwrap”属性。如果这个属性设置成true,ESB消息的payload将会被抽取出来并且只是payload被发送到ESB-unaware端点。如果这个属性设置成false,将会传递ESB消息,并且接收端点毕业时ESB-aware的,以便该端点能够处理消息。
即使配置文件中在router动作之后还配置了其他的动作,这些动作处理也不会发生作用。如果你必须触发剩余的动作,你可以使用Static Wiretap动作。
像Static Wiretap这类的router,Static Router仅仅是将消息路由到其他服务。还有一些根据消息内容来进行动态路由的router。关于基于内容路由的更多信息请参照ServiceGuide中的“什么是基于内容路由”一节。
Notifiers
Notifiers是成功或者错误信息传播到ESB-unaware端点的方式。你不能使用Notifiers与ESB-aware端点进行通信。这就是说,你不能在相同的channel上同时使用ESB-aware和ESB-unaware端点进行监听。如果说你想要和ESB-aware端点进行通信的话,考虑使用Couriers或者ServiceInvoker。
并不是所有的ESB-aware传输支持Notifiers。Notifiers允许传输的内容是十分简单的:或者是一个byte[],或者是一个String(通过调用payload的toString方法获得)。
注意:JMSNotifier发送的JMS消息的类型依赖于ESB消息的类型。这是不对的,因为ESB消息的类型不应该会影响Notifiers发送响应的方式。JBossESB 4.2.1CP02版本中,可以通过设置ESB消息的一个属性(org.jboss.soa.esb.message.transport.jms.nativeMessageType)来设置Notifier使用的消息类型。可能的设置的值是NotifyJMS.NativeMessage.text或者NotifyJMS.NativeMessage.object。为了兼容,默认的值依赖于ESB消息的类型,如果ESB消息是Serializable那么JMSNotifier的消息类型就是object,如果ESB消息是Xml,那么JMSNotifier的消息类型就是text。然而,我们建议您不要以依赖默认值。
就像上面所叙述的,一个listener的职责就是想一个消息传送端点那样传送消息到一个“动作处理管道”。每个listener的配置需要提供以下信息:
Ÿ Registry(参阅service-category, service-name, service-description and EPR-description 标签名)。如果你设置了可选的标签名remove-old-service为true,那么ESB将会从Register移除一个已有的服务入口,而不是添加一个新的实例。因此,这个属性应当慎用,因为这个服务都会移除,包含所有的EPRs。
Ÿ Listener类的实例化。(见ListenerClass标签)
Ÿ Listener服务的EPR。这是一个传送指定。下面二的例子对应的JMS EPR。(见connection-factory, destination-type, destination-name, jndi-type, jndi-URL and message-selector标签名)
Ÿ 动作处理管道。一个或者多个<action>元素,每个至少包含class标签名,这个标签决定了处理链中当前不愁的类。
这个配置例子中将会实例化一个listener对象,这个对象将会等待一个ESB消息,将每个消息传动到包含两步操作的动作处理管道。
1. action1 MyJMSListenerAction
2. notificationAction. An org.jboss.soa.esb.actions.SystemPrintln
下面这个动作类对调试你的xml动作配置很有用:
Action类是ESB用户使用框架满足特定需求的主要方式。ActionProcessingPipeline类要求action类只要要满足一下两个条件:
Ÿ 一个引用ConfigTree类型参数的公共构造方法
Ÿ 引用Message类型参数,返回Message类型结构的一个或者多个方法。
为了针对处理管道中的某步处理的结果返回一个通知,可以使用一个可选的公共回调方法,这个方法引用一个Message参数。org.jboss,soa.esb.listeners.message.ActionProcessingPipeline类将会对所有<action>元素配置动作进行一下处理:
1. 实例化class属性指定的类
2. 分析process属性的内容。
内容可以是一个逗号隔开的当前实例类的公共方法名列表。每个方法使用Message类型的参数并且返回Message类型的结果到管道的下一步。如果process属性没有确定,管道将会默认使用方法process使用一个action的多个方法和使用多个action配置段相比更为合适。因为那样的话,动作类实例只实例化一次,所有的方法都是在同一个对象上调用。减少了系统开销还能够保存实例化对象的状态信息。这种方法对于用户提供的新动作类是十分有用的,但是另一种方法(使用action列表)是重用已有动作类的方式
3. 列表里方法调用使用的都是前步返回的消息。
4. 如果某个步骤返还的值是null,这个管道将会立即停止处理。
5.在每个<action>元素中指定成功的回调方法。如果“process”属性里的方法都被成功执行,管道将会分析“onMethod”属性的内容。如果没有指定,将会进行下个<action>元素的处理。如果指定了方法名,这个方法将会被调用,所引用的Message是步骤3返回的。如果这个管道成功执行,OnMethod通知将会被按照从后向前的方式被所有的handler调用。
6.在每个<action>元素中指定失败的回调方法。如果发生一个异常,exceptionMethod 通知将会按照从当前action向前的方式被调用。如果当时没有指定exceptionMethod,将会输出一个错误日志。如果在任何一个process方法中抛出ActionProcessingFaultException异常,一个错误消息将会按照下节中定义的规则返回。错误消息的内容或者通过异常的getFaultMessage方法返回,或者是一个包含原有异常信息的默认的错误。
动作类可以帮助用户使用ESB来满足特定的需求,有可能需要额外的运行时配置。(比如上面xml里的notifier类需要< NotificationList>子元素)。每个<action>元素将会使用上面提到的属性并且会忽略其他属性和可选子元素。这些属性会通过必须的ConfigTree参数传输到动作类的构造函数。每个动作类都是根据自己对应的<action>元素实例化的。
注意:JBossESB4.3中,用于组成<action>标签中NotificationList元素的属性名没有经过验证。
Actions and Messages
消息的到来会触发动作。特定的action实现是被认为知道消息中的数据位置的。因为一个服务有可能使用任意数量的Action来实现,所有很有可能单个输入消息包含了和很多action的消息相同的信息。这样,action开发人员就有必要为数据在MessageBody中选择一个或者多个不同的位置,然后针对这些和服务使用者进行通信。
此外,因为action被链在一起,很有可能链中的一个动作修改了原始输入消息,甚至整个替换了。
注意:出于安全性的考虑,你应当在服务链中慎用不知道的actions。我们建议加密信息。
如果action共享输入消息里的数据,并且随着消息在链中传输会修改信息,默认情况下我们推荐保留原始信息一边处于链的下端的动作仍然能够获取原始消息。很显然,在某些情况下这是不可能或者不允许的。在JBossESB中,修改输入数据的Actions可以将数据放在以org.jboss.soa.esb.actions.post 命名的Body位置。这就是说,如果在链中有N个action,第N个Action可以按照正常方式找到原始数据,或者如果第N-1个action修改了数据,那么N将会在其他指定位置找到它。为了便于Action链,第N个Action可以通过查看org.jboss.soa.esb.actions.pre命名的Body位置来辨别Action N-2是不是修改了数据。
注意:就像上面提到的,你应该谨慎使用默认命名的Body位置,以防止链中的动作发生冲突。
Handling responses
在管道中,处理请求的机制有两种:隐式处理和显示处理。
如果是隐式处理,响应将会按照如下方式被处理:
Ÿ 如果管道中任何一个action返回一个null消息时候,不发送任何响应。
Ÿ 如果管道中最后一个action没有返回错误响应,将会发送一个回复到这个请求消息的ReplyTo EPR,如果没有设置,就会发送到请求消息的From EPR。如果一个事件中不包含路由响应的方式,将会在系统中记录一个错误消息。
如果是是显式处理:
Ÿ 如果管道被指定为“OneWay”,管道将不会发送响应。
Ÿ 如果管道被指定成“RequestResponse”,将会发送一个回复到这个请求消息的ReplyTo EPR,如果没有设置,就会发送到请求消息的From EPR。如果一个事件中没有指定EPR,将不会在系统中记录一个错误消息。
我们建议所有的动作管道使用显式的处理机制。只需要简单的在jboss-esb.xml中给“aciton”元素添加“mep”属性就可以。属性值可以是“OneWay”或者“RequestResponse”。
Error handling when processing actions
当处理一个动作链时,很有可能发生错误。这些错误应当在动作管道中抛出异常,然后终止管道的处理。就像前面提到的那样,包装在ActionProcessingException里的一个失败消息将会返回。如果关于错误的信息返回到发送方是十分重要的,应当设置FaultTo EPR。如果没有设置,JBossESB将会尝试将错误消息发送的ReplyTo EPR。如果没有设置ReplyTo EPR,会发送到From EPR.。如果都没有设置,将会在本地记录错误日志。
动作实现可以返回多种类型的错误消息。然而,JBossESB还支持下面的系统错误消息,这些类型都是由失败消息里的URI指定的,假如抛出异常并且没有具体的应用错误消息:
Ÿ urn:action/error/actionprocessingerror
这表明的动作链中的一个动作抛出一个ActionProcessingFaultException异常,但是不包含一个用于返回的失败消息。这个异常的细节将会包含在失败的“reason”字符中。
Ÿ urn:action/error/unexpectederror
在处理过程中捕捉到一个没有预料的异常。异常的详细将会在失败的原因字符中找到。
Ÿ urn:action/error/disabled
动作处理不可用
如果你的动作链处理过程中抛出一个异常,这个异常以一个FaultMessageException的形式回传到客户端,这个FaultMessageException是被Courier或者ServiceInvoker重新抛出的。当接收到失败消息时,也会抛出异常,这个异常包含了失败代码和原因,以及任何传播异常。
Meta-data and Filters
当一个消息在ESB中流转时,向消息中添加一些数据项是十分有用的,比如说消息进入系统和离开系统的时间。此外,动态的向消息中添加参数也很有必要。比如添加事务或者安全性信息。JBossESB是通过filter机制使网关和ESB节点具备这种能力的。
注意:在JbossESB4.2 MR3中,InputOutputFilter的filter属性名,包以及签名都发生了改变。
类org.jboss.soa.esb.filter.InputOutputFilter有两个方法:
Ÿ
public Message onOutput (Message msg, Map<String, Object>params) throws CourierException
当消息开始传输时,这个方法会被调用。一个实现可能会修改消息然后返回一个新版本。调用者可能会使用外部参数的形式提供其他信息。
Ÿ
public Message onInput (Message msg, Map<String, Object>params) throws CourierException
当消息从传输中流出时,这个方法会被调用。一个实现可能会修改消息然后返回一个新版本。调用者可能会使用外部参数的形式提供其他信息。
Filter是由jbossesb-properties.xml文件中的filters部分定义的,使用的属性是org.jboss.soa.esb.filter.<number>,<number>部分可以是任何用于数字,用于表明多个fileter被调用的顺序(按照由低到高的)。
JbossESB包含了org.jboss.internal.soa.esb.message.filter.MetaDataFilter和org.jboss.internal.soa.message.filter.GatewayFilter,这两个filter用于以properties的形式添加下面的数据项到消息,下表展示了可能的属性名和值.
名称 值
org.jboss.soa.esb.message.transport.type File, FTP, JMS, SQL, or Hibernate.
org.jboss.soa.esb.message.source 消息读取的文件名
org.jboss.soa.esb.message.time.dob 消息进入ESB的时间,比如发送的时间或者消息抵达网关的时间
org.jboss.soa.esb.message.time.dod 消息离开ESB的时间,比如消息死亡时间
org.jboss.soa.esb.gateway.original.file.name 如果消息是通过文件相关的网关节点接收的,这个元素将会包含消息来源文件的名字
org.jboss.soa.esb.gateway.original.queue.name 如果消息通过JMS网关节点接收,这个元素将包含接收消息队列的名字
org.jboss.soa.esb.gateway.original.url 如果消息通过SQL网关节点获得,这个元素将源包含元数据库的URL
注意:尽管在所有的ESB节点上部署GatewayFilter是安全的,但是只有当部署到网关节点上时才会向消息中添加信息。
可以通过创建和注册合适的filter来向消息中添加更多数据项。你的Filter可以根据在其他参数中是否存在下列名称实体来决定是否
名称 值
org.jboss.soa.esb.gateway.file 消息来源文件。如果这是个基于文件的网关节点时才会包含这个实体。
org.jboss.soa.esb.gateway.config 用于初始化网关实例的ConfigTree
要在网关节点运行。
注意:只有在JbossESB4.7中,file based, JMS and SQL gateways才支持GatewayFilter。
What is a Service?
JBossESB并没有对服务的组成做出限制。就像我们先前在文档中所说的,理想的SOA平台鼓励在客户端和服务之间进行松耦合方式的交互,这样消息就十分重要,并且实现细节是隐藏在一个抽象接口之后的。这就允许不用改变客户端就能改变实现。只有关于消息定义的更改才必须改变客户端。
就像上面我们看到的,JBossESB采用消息驱动方式实现服务定义和架构:客户端发送消息到服务并且基础服务接口本质上只有一个单独的process方法来操作接收到的消息。服务的内部就是一个或者多个动作,这些动作链接起来处理进入的消息。Action所作的工作是相互依赖的,比如更新数据库的表记录,或者调用一个EJB。
当开发一个服务时,首先要做的就是定义用于暴露给用户或者消费者的概念性的接口或者协定。这个协定要通过消息形式定义,例如payload是什么样子的,生成的响应消息(如果有)是什么类型的。
注意:定义之后,协定信息需要发布到注册处。现在,JBossESB不能自动完成这个操作。
只要客户端按照这个发布的协定工作,就能使用这个服务。服务怎样处理消息以及完成必要的工作,只是一个实现选择的问题。既可以通过多个动作完成,也可以通过单个动作完成。这就需要做一个权衡比较,比如考虑易管理性和可重用性。
注意:在后续版本中,我们会改善支持工具以方便服务的部署。
ServiceInvoker
从客户端的角度,Courier 接口和它的多个实现可以用于与服务交互。然而,这是一个相当低层次的方式,需要开发者编码来联系registry和处理失败。而且,因为JBossESB对无状态服务有失败恢复的特性,这就需要应用管理。参考“Advanced”章节获取关于失败恢复的详细信息
在JBossESB4.2中,引进了ServiceInvoker来简化开发工作。ServiceInvoker隐藏了低层次的细节并且和使用无状态服务失败恢复机制。因此,推荐在客户端通过ServiceInvoker接口来使用JBossESB的服务。
可以针对客户端要求交互的每一个服务创建一个ServiceInvoker实例。一旦实例被创建,就会和registry进行联系, registry就会查找主要的EPR,或者在失败恢复时查找替代的EPRs。
一旦被创建,客户端就能决定怎样同步地或者异步地发送消息到服务。在同步情况下,需要指定一个超时时间,这个超时时间决定了客户端会等待响应多长时间。如果在这段时间内没有接收到响应,就会抛出一个MessageDeliverException。
注意:从JBossESB4.5开始,由MessageDeliverException传送的ResponseTimeoutException会抛出。
如果使用了deliverSync方法,但是不能联系上Registry或者不能成功的查询到服务信息就意味着会抛出一个RegistryException。Timeout的值指的是服务失败,超负荷和不能在时间范围内响应或者处理需要的时间比设定的超时时间长。有些情况下,这些问题只是暂时的,在试一次可能就没问题了。
和服务进行通信过程的所有其他类型的失败将会抛出一个FaultMessageException异常。
注意:当使用deliverAsync方法时,所有错误都是作为MessageDeliverExcepion实例抛出的,真正的异常信息会嵌入到MessageDeliverExcepion实例中。
就像前面文档中介绍的,当发送一个消息时,可能在消息的头部指定To,ReplyTo和FaultTo的值。当使用ServiceInvoker时,因为已经在构建时就联系了registry,To字段就没必要了。事实上,不管在同步还是异步模式下,通过ServiceInvoker发送消息时,To字段都可以被忽略。在未来的JBossESB版本中,如果registry不能联系到一个活动的服务的话,很有可能会使用提供的To字段来作为ESB返回的传送目的地。
Transactions
一些Courier支持事务性传送语义( transactional delivery semantics),例如InVM和JMS。目前是基于JMS事务会话的。例如,消息被置于一个事务范围内的队列中,在相关事务提交之前不会被传送;然后他会被接受者在另一个事务范围内被获取。不幸运的是,对于一个同步请求响应交互来说,这可能会导致一个等待响应超时,因为发送方在结束这个传输事务之前。一直阻塞等待响应。
从JBossESB4.5开始,我们将防止阻塞并且会抛出一个IncompatibleTransactionScopeException异常。应用需要捕捉这个异常然后做相应处理。
服务和ServiceInvoker
在一个客户端服务环境下,客户端和服务这两个词汇用于代表两种角色,但是一个实体很有可能既是客户端也是服务。所以,不应该吧ServiceInvoker当做一个纯客户端;他也可以在你的服务中尤其是在Action中使用。例如,除了使用一个内置的基于内容的路由外,一个action可能希望根据一定业务规则将消息重新路由到一个不同的服务。或者一个Action为了日后管理需要会决定将特定类型的失败消息路由到Dead Letter Queue。
这样使用ServiceInvoker的好处是你的服务将会通过fail-over机制获利。这就是说,一个对某服务的one-way请求失败了,可以以一种增强的方式重新路由,而不必使开发变得复杂。
InVM Transport
InVm Transport是JBossESB4.3的新特性,这个特性提供了运行在相同JVM的服务之间进行通信的能力。这就意味着ServiceInvoker的实例能够调用同一个虚拟机里的服务而不发生任何网络或者消息序列化的开销。
注意:InVM是通过优化内部数据结构来获取性能优势的,内部数据是用于促进内部服务通讯的。 存储消息的队列不会持久化,这就意味着在发生失败事件时,消息很可能会丢失。并且,如果一个服务在队列清空之前关闭的话,消息将不会被传送。下面还会提到更多关于InVM的限制。因为jbossESB允许服务同时被多个不同的传输调用,你应当为你的服务的特定消息类型选择适合的传输方式,以获得高性能和高可靠性。
早期的版本中并不支持这种传输,并且要求每个服务都配置至少一个ESB Aware监听。但是现在不是必须的了。现在服务可以没有任何<listener>的配置但是仍然可以在相同虚拟机内被调用。这使配置十分简单。
InVM Scope
InvM服务调用范围可以通过<service>元素的“invmScope”属性来控制。ESB目前支持两种范围:
NONE :服务不能通过Invm传输调用、
GLOBAL :服务可以通过inVM传输调用,使用相同的加载类范围。
在未来的版本中会有一个LOCAL范围,将会使调用限制在同一个部署.ear归档中。
每个服务都可以通过设置<service>部分的imvmScope属性来制定各自的InVM范围。
例子4.2 服务的inVM scope可用
在jbossesb-properties.xml文件中可以通过属性“core:jboss.esb.invm.scope.default”来设置一个ESB部署的默认InVM范围。如果没有定义,默认的范围是“GLOBAL”。
InVM Transacted
InVM Listener可以在一个事务或者非事务的范围中按照和其他支持事务的传输一样的方式执行。可以通过显式或者隐式配置来控制这种行为。
事务范围的显式配置是通过定义<service>元素的“invmTransacted”属性设置的,并且比隐式配置优先级高。如果服务上包含另一个传输的事务配置,InVM listener 将是隐式事务的。目前其他的传输包括jms,scheduled或者sql。
Transaction Semantics
在JBossESB中,InVM传输不是事务性的,并且消息队列质保存在临时内存中。也就是说,一旦系统错误或者关闭,传输中的消息队列就会丢失。
注意:由于InVM队列的易失性,你可能不能获取ACID语义,特别是当与其他事务性资源联合使用时,比如数据库。但是大多数情况下,鉴于InVM的性能优势,它的这种缺点也就不重要了。如有ACID是必须的,我们建议使用其他事务性传输,比如JMS,Database。
当在一个事务中使用inVM时,在事务提交前,消息不会出现在接受者的消息队列里。尽管一旦消息被接受并且会加入队列,发送方就会被告知。如果在一个事务中,一个接受者试图从队列中获取消息时,如果该事务随后回滚的话,这个消息将会自动置于队列的后面。如果消息的发送者或者接受者需要知道事务的结果,他们或者需要直接监控事务的结果或者对事务进行序列化。
注意:当一个消息被事务管理者放在队列的后面,而不会放在相同的位置,这是为了的提高性能。如果你的应用需要制定消息的顺序,你需要考虑一个不同的传输或者将相关消息分组成一个单独的”wrapper”消息。
Threading
改变与InVM传输相关的listener线程数目:
Lock-step Delivery
InVM传输将消息发送到内存中的消息队列的性能消耗很低。如果关于服务使用的消息传输太频繁,消息队列就会崩溃了。InVM传输提供了一种“Lock-Step”传输机制来缓解这种情况。
“Lock-Step”传输方式保证了在服务能够接收消息之后才发送消息到服务。“Lock-Step”是通过在服务能够接收消息之前阻塞消息传输或者设定一个失效时间来实现这种能力的。
这不是一个同步传输方式。他不会等待一个响应来处理消息。他只是在服务移除队列里的这个消息前一直阻塞。
Lock-Step传输默认是不启用的,但是可以通过<service>的<property>进行设置:
inVMLockStep:Boolean型。用于控制是否开启LockStep传输。
inVMLockStepTimeout:等待消息被获取前,传输被阻塞的最大毫秒数。
注意:如果在事务下使用InVM,Lock-Step传输不可用。因为消息插入队列的时机是取决于相关事务的提交的,这有可能发生在lock-step等待期之内或者之外的任意一个时间。
Load Balancing
ServiceInvoker的一个特性是在目标服务有多个端点可用的情况下,会采用负载均衡的调用。ServiceInvoker支持多个负载均衡策略。
当使用ServiceInvoker时,如果一个InVM传输可用的话,调用服务时会优先采用InVM传输。其他的负载均衡策略只是在目标服务没有INVM端点时才会应用。
Pass-by-Value/Pass-by-Reference
默认情况下,InVm传输是通过引用传递消息。在一些情况下,这可能引起数据完整性的问题,如果通过不同的ClassLoader交换消息还会引起类转换的问题。。
根据值传递消息(避免了上述问题)可以通过在服务上设置属性“inVMPassByValue”为“true”来实现:
Listeners
Listerners封装了ESB-aware消息接收的端点。一旦接收到一个消息,一个listener会将消息传送进消息处理器管道,这个管道在将结果路由到“ReplyTo”端点之前会对消息进行处理。发生在管道中的动作处理可能包含以下步骤:在一个消息处理器中转换消息,在下一个处理器中应用业务逻辑。这些都是在处理结果路由到管道的下一个处理或者下个端点之前完成的。
注意:可以为listener配置许多参数,比如活动的线程数。更多设置请参照Defining Service Configuration。
Routers
Routers是ESB消息本身或者它的payload被路由到端点的方式。一些router支持“unwrap”属性。如果这个属性设置成true,ESB消息的payload将会被抽取出来并且只是payload被发送到ESB-unaware端点。如果这个属性设置成false,将会传递ESB消息,并且接收端点毕业时ESB-aware的,以便该端点能够处理消息。
即使配置文件中在router动作之后还配置了其他的动作,这些动作处理也不会发生作用。如果你必须触发剩余的动作,你可以使用Static Wiretap动作。
像Static Wiretap这类的router,Static Router仅仅是将消息路由到其他服务。还有一些根据消息内容来进行动态路由的router。关于基于内容路由的更多信息请参照ServiceGuide中的“什么是基于内容路由”一节。
Notifiers
Notifiers是成功或者错误信息传播到ESB-unaware端点的方式。你不能使用Notifiers与ESB-aware端点进行通信。这就是说,你不能在相同的channel上同时使用ESB-aware和ESB-unaware端点进行监听。如果说你想要和ESB-aware端点进行通信的话,考虑使用Couriers或者ServiceInvoker。
并不是所有的ESB-aware传输支持Notifiers。Notifiers允许传输的内容是十分简单的:或者是一个byte[],或者是一个String(通过调用payload的toString方法获得)。
注意:JMSNotifier发送的JMS消息的类型依赖于ESB消息的类型。这是不对的,因为ESB消息的类型不应该会影响Notifiers发送响应的方式。JBossESB 4.2.1CP02版本中,可以通过设置ESB消息的一个属性(org.jboss.soa.esb.message.transport.jms.nativeMessageType)来设置Notifier使用的消息类型。可能的设置的值是NotifyJMS.NativeMessage.text或者NotifyJMS.NativeMessage.object。为了兼容,默认的值依赖于ESB消息的类型,如果ESB消息是Serializable那么JMSNotifier的消息类型就是object,如果ESB消息是Xml,那么JMSNotifier的消息类型就是text。然而,我们建议您不要以依赖默认值。
就像上面所叙述的,一个listener的职责就是想一个消息传送端点那样传送消息到一个“动作处理管道”。每个listener的配置需要提供以下信息:
Ÿ Registry(参阅service-category, service-name, service-description and EPR-description 标签名)。如果你设置了可选的标签名remove-old-service为true,那么ESB将会从Register移除一个已有的服务入口,而不是添加一个新的实例。因此,这个属性应当慎用,因为这个服务都会移除,包含所有的EPRs。
Ÿ Listener类的实例化。(见ListenerClass标签)
Ÿ Listener服务的EPR。这是一个传送指定。下面二的例子对应的JMS EPR。(见connection-factory, destination-type, destination-name, jndi-type, jndi-URL and message-selector标签名)
Ÿ 动作处理管道。一个或者多个<action>元素,每个至少包含class标签名,这个标签决定了处理链中当前不愁的类。
<?xml version = "1.0" encoding = "UTF-8"?> <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/x ml/jbossesb-1.0.1.xsd" parameterReloadSecs="5"> <providers> <jms-provider name="JBossMQ" connection-factory="ConnectionFactory" jndi-URL="jnp://127.0.0.1:1099" jndi-context-factory="org.jnp.interfaces.NamingContextFactory" jndi-pkg-prefix="org.jboss.namingrg.jnp.interfaces"> <jms-bus busid="quickstartGwChannel"> <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_helloworld_Request_gw" /> </jms-bus> <jms-bus busid="quickstartEsbChannel"> <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_helloworld_Request_esb" /> </jms-bus> </jms-provider> </providers> <services> <service category="FirstServiceESB" name="SimpleListener" description="Hello World"> <listeners> <jms-listener name="JMS-Gateway" busidref="quickstartGwChannel" maxThreads="1" is-gateway="true" /> <jms-listener name="helloWorld" busidref="quickstartEsbChannel" maxThreads="1" /> </listeners> <actions> <action name="action1" class="org.jboss.soa.esb.samples.quickstart.helloworld.MyJMSListenerAction" process="displayMessage" /> <action name="notificationAction" class="org.jboss.soa.esb.actions.Notifier"> <property name="okMethod" value="notifyOK" /> <property name="notification-details"> <NotificationList type="ok"> <target class="NotifyConsole"/> </NotificationList> <NotificationList type="err"> <target class="NotifyConsole"/> </NotificationList> </property> </action> </actions> </service> </services> </jbossesb>
这个配置例子中将会实例化一个listener对象,这个对象将会等待一个ESB消息,将每个消息传动到包含两步操作的动作处理管道。
1. action1 MyJMSListenerAction
2. notificationAction. An org.jboss.soa.esb.actions.SystemPrintln
下面这个动作类对调试你的xml动作配置很有用:
public class MyJMSListenerAction { ConfigTree _config; public MyJMSListenerAction(ConfigTree config) { _config = config; } public Message process (Message message) throws Exception { System.out.println(message.getBody().get()); return message; } }
Action类是ESB用户使用框架满足特定需求的主要方式。ActionProcessingPipeline类要求action类只要要满足一下两个条件:
Ÿ 一个引用ConfigTree类型参数的公共构造方法
Ÿ 引用Message类型参数,返回Message类型结构的一个或者多个方法。
为了针对处理管道中的某步处理的结果返回一个通知,可以使用一个可选的公共回调方法,这个方法引用一个Message参数。org.jboss,soa.esb.listeners.message.ActionProcessingPipeline类将会对所有<action>元素配置动作进行一下处理:
1. 实例化class属性指定的类
2. 分析process属性的内容。
内容可以是一个逗号隔开的当前实例类的公共方法名列表。每个方法使用Message类型的参数并且返回Message类型的结果到管道的下一步。如果process属性没有确定,管道将会默认使用方法process使用一个action的多个方法和使用多个action配置段相比更为合适。因为那样的话,动作类实例只实例化一次,所有的方法都是在同一个对象上调用。减少了系统开销还能够保存实例化对象的状态信息。这种方法对于用户提供的新动作类是十分有用的,但是另一种方法(使用action列表)是重用已有动作类的方式
3. 列表里方法调用使用的都是前步返回的消息。
4. 如果某个步骤返还的值是null,这个管道将会立即停止处理。
5.在每个<action>元素中指定成功的回调方法。如果“process”属性里的方法都被成功执行,管道将会分析“onMethod”属性的内容。如果没有指定,将会进行下个<action>元素的处理。如果指定了方法名,这个方法将会被调用,所引用的Message是步骤3返回的。如果这个管道成功执行,OnMethod通知将会被按照从后向前的方式被所有的handler调用。
6.在每个<action>元素中指定失败的回调方法。如果发生一个异常,exceptionMethod 通知将会按照从当前action向前的方式被调用。如果当时没有指定exceptionMethod,将会输出一个错误日志。如果在任何一个process方法中抛出ActionProcessingFaultException异常,一个错误消息将会按照下节中定义的规则返回。错误消息的内容或者通过异常的getFaultMessage方法返回,或者是一个包含原有异常信息的默认的错误。
动作类可以帮助用户使用ESB来满足特定的需求,有可能需要额外的运行时配置。(比如上面xml里的notifier类需要< NotificationList>子元素)。每个<action>元素将会使用上面提到的属性并且会忽略其他属性和可选子元素。这些属性会通过必须的ConfigTree参数传输到动作类的构造函数。每个动作类都是根据自己对应的<action>元素实例化的。
注意:JBossESB4.3中,用于组成<action>标签中NotificationList元素的属性名没有经过验证。
Actions and Messages
消息的到来会触发动作。特定的action实现是被认为知道消息中的数据位置的。因为一个服务有可能使用任意数量的Action来实现,所有很有可能单个输入消息包含了和很多action的消息相同的信息。这样,action开发人员就有必要为数据在MessageBody中选择一个或者多个不同的位置,然后针对这些和服务使用者进行通信。
此外,因为action被链在一起,很有可能链中的一个动作修改了原始输入消息,甚至整个替换了。
注意:出于安全性的考虑,你应当在服务链中慎用不知道的actions。我们建议加密信息。
如果action共享输入消息里的数据,并且随着消息在链中传输会修改信息,默认情况下我们推荐保留原始信息一边处于链的下端的动作仍然能够获取原始消息。很显然,在某些情况下这是不可能或者不允许的。在JBossESB中,修改输入数据的Actions可以将数据放在以org.jboss.soa.esb.actions.post 命名的Body位置。这就是说,如果在链中有N个action,第N个Action可以按照正常方式找到原始数据,或者如果第N-1个action修改了数据,那么N将会在其他指定位置找到它。为了便于Action链,第N个Action可以通过查看org.jboss.soa.esb.actions.pre命名的Body位置来辨别Action N-2是不是修改了数据。
注意:就像上面提到的,你应该谨慎使用默认命名的Body位置,以防止链中的动作发生冲突。
Handling responses
在管道中,处理请求的机制有两种:隐式处理和显示处理。
如果是隐式处理,响应将会按照如下方式被处理:
Ÿ 如果管道中任何一个action返回一个null消息时候,不发送任何响应。
Ÿ 如果管道中最后一个action没有返回错误响应,将会发送一个回复到这个请求消息的ReplyTo EPR,如果没有设置,就会发送到请求消息的From EPR。如果一个事件中不包含路由响应的方式,将会在系统中记录一个错误消息。
如果是是显式处理:
Ÿ 如果管道被指定为“OneWay”,管道将不会发送响应。
Ÿ 如果管道被指定成“RequestResponse”,将会发送一个回复到这个请求消息的ReplyTo EPR,如果没有设置,就会发送到请求消息的From EPR。如果一个事件中没有指定EPR,将不会在系统中记录一个错误消息。
我们建议所有的动作管道使用显式的处理机制。只需要简单的在jboss-esb.xml中给“aciton”元素添加“mep”属性就可以。属性值可以是“OneWay”或者“RequestResponse”。
Error handling when processing actions
当处理一个动作链时,很有可能发生错误。这些错误应当在动作管道中抛出异常,然后终止管道的处理。就像前面提到的那样,包装在ActionProcessingException里的一个失败消息将会返回。如果关于错误的信息返回到发送方是十分重要的,应当设置FaultTo EPR。如果没有设置,JBossESB将会尝试将错误消息发送的ReplyTo EPR。如果没有设置ReplyTo EPR,会发送到From EPR.。如果都没有设置,将会在本地记录错误日志。
动作实现可以返回多种类型的错误消息。然而,JBossESB还支持下面的系统错误消息,这些类型都是由失败消息里的URI指定的,假如抛出异常并且没有具体的应用错误消息:
Ÿ urn:action/error/actionprocessingerror
这表明的动作链中的一个动作抛出一个ActionProcessingFaultException异常,但是不包含一个用于返回的失败消息。这个异常的细节将会包含在失败的“reason”字符中。
Ÿ urn:action/error/unexpectederror
在处理过程中捕捉到一个没有预料的异常。异常的详细将会在失败的原因字符中找到。
Ÿ urn:action/error/disabled
动作处理不可用
如果你的动作链处理过程中抛出一个异常,这个异常以一个FaultMessageException的形式回传到客户端,这个FaultMessageException是被Courier或者ServiceInvoker重新抛出的。当接收到失败消息时,也会抛出异常,这个异常包含了失败代码和原因,以及任何传播异常。
Meta-data and Filters
当一个消息在ESB中流转时,向消息中添加一些数据项是十分有用的,比如说消息进入系统和离开系统的时间。此外,动态的向消息中添加参数也很有必要。比如添加事务或者安全性信息。JBossESB是通过filter机制使网关和ESB节点具备这种能力的。
注意:在JbossESB4.2 MR3中,InputOutputFilter的filter属性名,包以及签名都发生了改变。
类org.jboss.soa.esb.filter.InputOutputFilter有两个方法:
Ÿ
public Message onOutput (Message msg, Map<String, Object>params) throws CourierException
当消息开始传输时,这个方法会被调用。一个实现可能会修改消息然后返回一个新版本。调用者可能会使用外部参数的形式提供其他信息。
Ÿ
public Message onInput (Message msg, Map<String, Object>params) throws CourierException
当消息从传输中流出时,这个方法会被调用。一个实现可能会修改消息然后返回一个新版本。调用者可能会使用外部参数的形式提供其他信息。
Filter是由jbossesb-properties.xml文件中的filters部分定义的,使用的属性是org.jboss.soa.esb.filter.<number>,<number>部分可以是任何用于数字,用于表明多个fileter被调用的顺序(按照由低到高的)。
JbossESB包含了org.jboss.internal.soa.esb.message.filter.MetaDataFilter和org.jboss.internal.soa.message.filter.GatewayFilter,这两个filter用于以properties的形式添加下面的数据项到消息,下表展示了可能的属性名和值.
名称 值
org.jboss.soa.esb.message.transport.type File, FTP, JMS, SQL, or Hibernate.
org.jboss.soa.esb.message.source 消息读取的文件名
org.jboss.soa.esb.message.time.dob 消息进入ESB的时间,比如发送的时间或者消息抵达网关的时间
org.jboss.soa.esb.message.time.dod 消息离开ESB的时间,比如消息死亡时间
org.jboss.soa.esb.gateway.original.file.name 如果消息是通过文件相关的网关节点接收的,这个元素将会包含消息来源文件的名字
org.jboss.soa.esb.gateway.original.queue.name 如果消息通过JMS网关节点接收,这个元素将包含接收消息队列的名字
org.jboss.soa.esb.gateway.original.url 如果消息通过SQL网关节点获得,这个元素将源包含元数据库的URL
注意:尽管在所有的ESB节点上部署GatewayFilter是安全的,但是只有当部署到网关节点上时才会向消息中添加信息。
可以通过创建和注册合适的filter来向消息中添加更多数据项。你的Filter可以根据在其他参数中是否存在下列名称实体来决定是否
名称 值
org.jboss.soa.esb.gateway.file 消息来源文件。如果这是个基于文件的网关节点时才会包含这个实体。
org.jboss.soa.esb.gateway.config 用于初始化网关实例的ConfigTree
要在网关节点运行。
注意:只有在JbossESB4.7中,file based, JMS and SQL gateways才支持GatewayFilter。
What is a Service?
JBossESB并没有对服务的组成做出限制。就像我们先前在文档中所说的,理想的SOA平台鼓励在客户端和服务之间进行松耦合方式的交互,这样消息就十分重要,并且实现细节是隐藏在一个抽象接口之后的。这就允许不用改变客户端就能改变实现。只有关于消息定义的更改才必须改变客户端。
就像上面我们看到的,JBossESB采用消息驱动方式实现服务定义和架构:客户端发送消息到服务并且基础服务接口本质上只有一个单独的process方法来操作接收到的消息。服务的内部就是一个或者多个动作,这些动作链接起来处理进入的消息。Action所作的工作是相互依赖的,比如更新数据库的表记录,或者调用一个EJB。
当开发一个服务时,首先要做的就是定义用于暴露给用户或者消费者的概念性的接口或者协定。这个协定要通过消息形式定义,例如payload是什么样子的,生成的响应消息(如果有)是什么类型的。
注意:定义之后,协定信息需要发布到注册处。现在,JBossESB不能自动完成这个操作。
只要客户端按照这个发布的协定工作,就能使用这个服务。服务怎样处理消息以及完成必要的工作,只是一个实现选择的问题。既可以通过多个动作完成,也可以通过单个动作完成。这就需要做一个权衡比较,比如考虑易管理性和可重用性。
注意:在后续版本中,我们会改善支持工具以方便服务的部署。
ServiceInvoker
从客户端的角度,Courier 接口和它的多个实现可以用于与服务交互。然而,这是一个相当低层次的方式,需要开发者编码来联系registry和处理失败。而且,因为JBossESB对无状态服务有失败恢复的特性,这就需要应用管理。参考“Advanced”章节获取关于失败恢复的详细信息
在JBossESB4.2中,引进了ServiceInvoker来简化开发工作。ServiceInvoker隐藏了低层次的细节并且和使用无状态服务失败恢复机制。因此,推荐在客户端通过ServiceInvoker接口来使用JBossESB的服务。
public class ServiceInvoker { public ServiceInvoker(Service service) throws MessageDeliverException; public ServiceInvoker(String serviceCategory, String serviceName) throws MessageDeliverException; public Message deliverSync(Message message, long timeoutMillis) throws MessageDeliverException, RegistryException, FaultMessageException; public void deliverAsync(Message message) throws MessageDeliverException; }
可以针对客户端要求交互的每一个服务创建一个ServiceInvoker实例。一旦实例被创建,就会和registry进行联系, registry就会查找主要的EPR,或者在失败恢复时查找替代的EPRs。
一旦被创建,客户端就能决定怎样同步地或者异步地发送消息到服务。在同步情况下,需要指定一个超时时间,这个超时时间决定了客户端会等待响应多长时间。如果在这段时间内没有接收到响应,就会抛出一个MessageDeliverException。
注意:从JBossESB4.5开始,由MessageDeliverException传送的ResponseTimeoutException会抛出。
如果使用了deliverSync方法,但是不能联系上Registry或者不能成功的查询到服务信息就意味着会抛出一个RegistryException。Timeout的值指的是服务失败,超负荷和不能在时间范围内响应或者处理需要的时间比设定的超时时间长。有些情况下,这些问题只是暂时的,在试一次可能就没问题了。
和服务进行通信过程的所有其他类型的失败将会抛出一个FaultMessageException异常。
注意:当使用deliverAsync方法时,所有错误都是作为MessageDeliverExcepion实例抛出的,真正的异常信息会嵌入到MessageDeliverExcepion实例中。
就像前面文档中介绍的,当发送一个消息时,可能在消息的头部指定To,ReplyTo和FaultTo的值。当使用ServiceInvoker时,因为已经在构建时就联系了registry,To字段就没必要了。事实上,不管在同步还是异步模式下,通过ServiceInvoker发送消息时,To字段都可以被忽略。在未来的JBossESB版本中,如果registry不能联系到一个活动的服务的话,很有可能会使用提供的To字段来作为ESB返回的传送目的地。
Transactions
一些Courier支持事务性传送语义( transactional delivery semantics),例如InVM和JMS。目前是基于JMS事务会话的。例如,消息被置于一个事务范围内的队列中,在相关事务提交之前不会被传送;然后他会被接受者在另一个事务范围内被获取。不幸运的是,对于一个同步请求响应交互来说,这可能会导致一个等待响应超时,因为发送方在结束这个传输事务之前。一直阻塞等待响应。
从JBossESB4.5开始,我们将防止阻塞并且会抛出一个IncompatibleTransactionScopeException异常。应用需要捕捉这个异常然后做相应处理。
服务和ServiceInvoker
在一个客户端服务环境下,客户端和服务这两个词汇用于代表两种角色,但是一个实体很有可能既是客户端也是服务。所以,不应该吧ServiceInvoker当做一个纯客户端;他也可以在你的服务中尤其是在Action中使用。例如,除了使用一个内置的基于内容的路由外,一个action可能希望根据一定业务规则将消息重新路由到一个不同的服务。或者一个Action为了日后管理需要会决定将特定类型的失败消息路由到Dead Letter Queue。
这样使用ServiceInvoker的好处是你的服务将会通过fail-over机制获利。这就是说,一个对某服务的one-way请求失败了,可以以一种增强的方式重新路由,而不必使开发变得复杂。
InVM Transport
InVm Transport是JBossESB4.3的新特性,这个特性提供了运行在相同JVM的服务之间进行通信的能力。这就意味着ServiceInvoker的实例能够调用同一个虚拟机里的服务而不发生任何网络或者消息序列化的开销。
注意:InVM是通过优化内部数据结构来获取性能优势的,内部数据是用于促进内部服务通讯的。 存储消息的队列不会持久化,这就意味着在发生失败事件时,消息很可能会丢失。并且,如果一个服务在队列清空之前关闭的话,消息将不会被传送。下面还会提到更多关于InVM的限制。因为jbossESB允许服务同时被多个不同的传输调用,你应当为你的服务的特定消息类型选择适合的传输方式,以获得高性能和高可靠性。
早期的版本中并不支持这种传输,并且要求每个服务都配置至少一个ESB Aware监听。但是现在不是必须的了。现在服务可以没有任何<listener>的配置但是仍然可以在相同虚拟机内被调用。这使配置十分简单。
<service category="ServiceCat" name="ServiceName" description="Test Service"> <actions mep="RequestResponse"> <action name="action" class="org.jboss.soa.esb.listeners.SetPayloadAction"> <property name="payload" value="Tom Fennelly" /> </action> </actions> </service>
InVM Scope
InvM服务调用范围可以通过<service>元素的“invmScope”属性来控制。ESB目前支持两种范围:
NONE :服务不能通过Invm传输调用、
GLOBAL :服务可以通过inVM传输调用,使用相同的加载类范围。
在未来的版本中会有一个LOCAL范围,将会使调用限制在同一个部署.ear归档中。
每个服务都可以通过设置<service>部分的imvmScope属性来制定各自的InVM范围。
<service category="ServiceCat" name="ServiceName" invmScope="GLOBAL" description="Test Service"> <actions mep="RequestResponse"> <action name="action" class="org.jboss.soa.esb.listeners.SetPayloadAction"> <property name="payload" value="Tom Fennelly" /> </action> </actions> </service>
例子4.2 服务的inVM scope可用
在jbossesb-properties.xml文件中可以通过属性“core:jboss.esb.invm.scope.default”来设置一个ESB部署的默认InVM范围。如果没有定义,默认的范围是“GLOBAL”。
InVM Transacted
InVM Listener可以在一个事务或者非事务的范围中按照和其他支持事务的传输一样的方式执行。可以通过显式或者隐式配置来控制这种行为。
事务范围的显式配置是通过定义<service>元素的“invmTransacted”属性设置的,并且比隐式配置优先级高。如果服务上包含另一个传输的事务配置,InVM listener 将是隐式事务的。目前其他的传输包括jms,scheduled或者sql。
Transaction Semantics
在JBossESB中,InVM传输不是事务性的,并且消息队列质保存在临时内存中。也就是说,一旦系统错误或者关闭,传输中的消息队列就会丢失。
注意:由于InVM队列的易失性,你可能不能获取ACID语义,特别是当与其他事务性资源联合使用时,比如数据库。但是大多数情况下,鉴于InVM的性能优势,它的这种缺点也就不重要了。如有ACID是必须的,我们建议使用其他事务性传输,比如JMS,Database。
当在一个事务中使用inVM时,在事务提交前,消息不会出现在接受者的消息队列里。尽管一旦消息被接受并且会加入队列,发送方就会被告知。如果在一个事务中,一个接受者试图从队列中获取消息时,如果该事务随后回滚的话,这个消息将会自动置于队列的后面。如果消息的发送者或者接受者需要知道事务的结果,他们或者需要直接监控事务的结果或者对事务进行序列化。
注意:当一个消息被事务管理者放在队列的后面,而不会放在相同的位置,这是为了的提高性能。如果你的应用需要制定消息的顺序,你需要考虑一个不同的传输或者将相关消息分组成一个单独的”wrapper”消息。
Threading
改变与InVM传输相关的listener线程数目:
<service category="HelloWorld" name="Service2" description="Service 2" i nvmScope="GLOBAL"> <property name="maxThreads" value="100" /> <listeners>... <actions>...
Lock-step Delivery
InVM传输将消息发送到内存中的消息队列的性能消耗很低。如果关于服务使用的消息传输太频繁,消息队列就会崩溃了。InVM传输提供了一种“Lock-Step”传输机制来缓解这种情况。
“Lock-Step”传输方式保证了在服务能够接收消息之后才发送消息到服务。“Lock-Step”是通过在服务能够接收消息之前阻塞消息传输或者设定一个失效时间来实现这种能力的。
这不是一个同步传输方式。他不会等待一个响应来处理消息。他只是在服务移除队列里的这个消息前一直阻塞。
Lock-Step传输默认是不启用的,但是可以通过<service>的<property>进行设置:
inVMLockStep:Boolean型。用于控制是否开启LockStep传输。
inVMLockStepTimeout:等待消息被获取前,传输被阻塞的最大毫秒数。
<service category="ServiceCat" name="Service2" description="Test Service"> <property name="inVMLockStep" value="true" /> <property name="inVMLockStepTimeout" value="4000" /> <actions mep="RequestResponse"> <action name="action" class="org.jboss.soa.esb.mock.MockAction" /> </actions> </service>
注意:如果在事务下使用InVM,Lock-Step传输不可用。因为消息插入队列的时机是取决于相关事务的提交的,这有可能发生在lock-step等待期之内或者之外的任意一个时间。
Load Balancing
ServiceInvoker的一个特性是在目标服务有多个端点可用的情况下,会采用负载均衡的调用。ServiceInvoker支持多个负载均衡策略。
当使用ServiceInvoker时,如果一个InVM传输可用的话,调用服务时会优先采用InVM传输。其他的负载均衡策略只是在目标服务没有INVM端点时才会应用。
Pass-by-Value/Pass-by-Reference
默认情况下,InVm传输是通过引用传递消息。在一些情况下,这可能引起数据完整性的问题,如果通过不同的ClassLoader交换消息还会引起类转换的问题。。
根据值传递消息(避免了上述问题)可以通过在服务上设置属性“inVMPassByValue”为“true”来实现:
<service category="ServiceCat" name="Service2" description="Test Service"> <property name="inVMPassByValue" value="true" /> <actions mep="RequestResponse"> <action name="action" class="org.jboss.soa.esb.mock.MockAction" /> </actions> </service>
发表评论
-
JBoss Enterprise SOA Platform 4.3 编程指南翻译之十二——开发自定义的动作
2012-02-23 11:10 116112. 开发自定义的动作 只要简单的实现了org.jb ... -
JBossESB4.7 Programming Guide 翻译之八--Defining Service Configurations
2012-02-23 11:09 1541Defining Service Configurations ... -
JBoss Enterprise SOA Platform 4.3 编程指南翻译之三——服务和消息
2012-02-23 10:58 23543.服务和消息 基于面向服务的原则,JBoss ESB ... -
JBoss ESB概述(一):ESB概述
2012-02-23 09:11 1458ESB概述 ESB与EAI ...
相关推荐
opencv-python-4.7.0.72-cp37-abi3-win-amd64.whl
arm linux gcc 交叉编译器 gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux.tar.bz2.tar
LS-PrePost是一款由ANSYS公司开发的专业有限元前处理器,它主要用于创建、编辑和预处理复杂的几何模型,以及对模型进行网格划分。在这款软件的4.7.20-x64-24Aug2020版本中,我们看到了64位系统的支持,这表明它可以...
Ace_todolist-1.1.4.7-py3-none-any.whl.zip 是一个包含Python软件包的压缩文件,主要用于Python开发环境。这个文件名中的 "Ace_todolist" 指的是一个名为 "Ace Todo List" 的特定应用程序或库,版本号为1.1.4.7。...
arm-linux-gcc编译器,32位的4.7-2013.5版本,还有4.6~4.9的版本的arm-linuxgcc编译器在我的资源中可以找到
Av1an-4.7-py3-none-any.whl.zip
总的来说,Gradle-4.7-bin.zip 提供了一个便捷的方式来获取和使用Gradle 4.7版本,这对于Android开发者和其他使用Gradle的项目来说是一个宝贵的资源。通过快速部署新版本,开发者可以利用其最新功能和优化,提高开发...
opencv_python-4.7.0.72-cp37-cp37m-linux_armv7l.whl
SonarScanner 4.7是SonarQube的配套扫描工具,用于代码质量检测。SonarQube是一款开源平台,专注于代码质量管理,它能够自动分析源代码,发现潜在的缺陷、漏洞以及代码异味,帮助开发者提升软件的质量和安全性。这款...
内含fontawesome-pro-5.14.0、FontAwesome v4.7、fontawesome-free-6.5.1三个版本
树莓派3的linaro系列系统的交叉编译器
FastReport v4.7.91 Professional for D4-D2009 Full Source 已经解决中文菜单显示问题
gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux.tar
Eclipse64位4.7氧气版eclipse-jee-oxygen-R-win32-x86_64.zip支持jdk1.8 Eclipse 支持jdk1.8 64位 oxygen 氧气版 eclipse-jee-oxygen-R-win32-x86_64.zip 更多eclipse版本可看查看我的系列,欢迎下载~
网校搭建MeEdu-Admin v4.7代码管理端部署meedu-admin-v4.7.zip
Eclipse32位4.7氧气版eclipse-jee-oxygen-R-win32.zip支持jdk1.8 Eclipse 支持jdk1.8 32位 oxygen 氧气版 eclipse-jee-oxygen-R-win32.zip 更多eclipse版本可看查看我的系列,欢迎下载~
opencv_python-4.7.0.72-cp311-cp311-linux_armv7l.whl
FastReport v4.7.109 Professional for D4-D2009 Full Source 这是我自己使用的中文修复版,里面包含了从企业版中提取的ClientServer组件,并加上了D2010的包文件,编译安装都没问题,使用上有没有问题就不知道了...