关于SpringSide2 MDP补充说明
作者:cctvx1 (SpringSide.org.cn 保留版权,转载请注明出处http://wiki.springside.org.cn/display/springside/ActiveMQ
)
1.Message Driven POJO
1.1 Container
在SpringSide2(以下简称为ss2)中主要使用Spring 2.0+ActiveMQ来完成MDP,让开发者能够更简单的使用消息驱动,Spring 2.0提供了更好的MDP支持,你可以直接使用
org.springframework.jms.listener.DefaultMessageListenerContainer 来充当Container 接受消息,同时ss2也提供使用jencks充当container的配置文件,jencks能够更好的管理pool或者线程池。
1.2 MessageListenerAdapter
为了让POJO接受消息,还需要配置MessageListenerAdapter,org.springframework.jms.listener.adapter.MessageListenerAdapter能够让一个普通的POJO接受消息,ss2的
org.springside.bookstore.components.activemq.OrderMessageConsumer 就是一个用来接受消息的POJO,这里无论使用哪种Container 都能够使用Spring 提供的MessageListenerAdapter
- <!- Message Driven POJO (MDP) ->
- <bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
- <constructor-arg>
- <bean class="org.springside.bookstore.components.activemq.OrderMessageConsumer">
- <property name="mailService" ref="mailService"/>
- </bean>
- </constructor-arg>
- <!- may be other method ->
- <property name="defaultListenerMethod" value="sendEmail" />
- <!- custom MessageConverter define ->
- <property name="messageConverter" ref="orderMessageConverter" />
- </bean>
而且在配置中,也能够通过配置defaultListenerMethod 指定接受消息的方法。
1.3 MessageConverter
Spring提供了一个消息的封装接口MessageConverter,我们需要自行去实现它,从而完成消息的定义,封装.
public Message toMessage(Object obj, Session session) throws JMSException,
MessageConversionException
public Object fromMessage(Message msg) throws JMSException,
MessageConversionException
toMessage 提供了一个消息打包的调用,Spring会在jmstemplate调用template.convertAndSend(this.destination, order);的时候 调用toMessage方法
同时,会在MessageListenerAdapter收到原始的jms消息后,首先调用formMessage,然后把消息解包成普通对象,作为参数再返给OrderMessageConsumer的sendEmail方法
1.4 Cosumer 和 Producter
SpringSide 2 的OrderMessageConsumer和OrderMessageProducer 本身都很简单,Producer仅仅调用jmstemplate的converAndSend方法,而Consumer则处理解包后的消息,这里就是处理业务对象Order
2.使用正确的Message 类型
由于springside2 使用的是ActiveMQ,所以我们还是以ActiveMQ为例讲解具体的Message类型
2.1 ActiveMQObjectMessage 使用注意事项
SS2中,在convert中使用的是ActiveMQObjectMessage来封装消息。具体代码参见OrderMessageConvert
ActiveMQObjectMessage 这里需要注意的是如果你使用的是setObjectProperty(String key,Object value),那么这里的value要不然是Strings 或者是 primitive类型,要不然就只能是map或者list。这里还有要说明的是,如果你使用embedded-vm(未使用持久化)的时候,即使你的Order,OrderItem,Product未实现Serialzable接口,也不会报错,但是一旦你的broker配置了持久化或者是远程broker或者使用其他的transport协议的时候,就会提示Order is not primitive type,因此在springside2 最新的版本中,OrderMessageConver的包装形式已经作了修改,会将Order序列化成byte然后发送。也就是我们可以将消息的定义在Conver完成,而对于上层业务来说是透明的,如果你不想Order,OrderItem,Product实现Serializable接口,那么你就需要在Convert作其他的封装用来发送消息.
2.2 JMS 1.1 对于消息主体类型的说明
JMS provides five forms of message body. Each form is defined by a message nterface:
• StreamMessage - a message whose body contains a stream of Java primitive values. It is filled and read sequentially.
• MapMessage - a message whose body contains a set of name-value pairs where names are Strings and values are Java primitive types. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
• TextMessage - a message whose body contains a java.lang.String. The inclusion of this message type is based on our presumption that String messages will be used extensively. One reason for this is that XML will likely become a popular mechanism for representing the content of JMS messages.
• ObjectMessage - a message that contains a Serializable Java object. If a collection of Java objects is needed, one of the collection classes provided in JDK 1.2 can be used.
• BytesMessage - a message that contains a stream of uninterpreted bytes.This message type is for literally encoding a body to match an existing message format. In many cases, it will be possible to use one of the other,self-defining, message types instead. Although JMS allows the use of message properties with byte messages, they are typically not used, since the inclusion of properties may affect the format.