目前的项目要求尽量不要使用EJB来完成本来只有EJB才能实现的功能,比如声明式的事务管理。在做到异步处理某个业务的时候,发现Spring并没有提供MDB的替代实现,看来只能自己实现了。
由于这个相对比较简单,现在把相关的代码整理在这里:
1. 首先在Spring配置文件中定义ConnectionFactory和一个Destination
<bean id=”connectionFactory” class=”org.springframework.jndi.JndiObjectFactoryBean”>
<property name=”jndiName”><value>ConnectionFactory</value></property>
</bean>
<bean id=”queue” class=”org.springframework.jndi.JndiObjectFactoryBean”>
<property name=”jndiName”><value>queue/MyQueue</value></property>
</bean>
2. Send Message
我们可以使用Spring提供的JmsTemplate来实现消息发送的功能:
JmsTemplate template = new JmsTemplate( connectionFactory );
template.send( destination, new MessageCreator()
{
public Message createMessage( Session session ) throws JMSException
{
return session.createTextMessage( message );
}
} );
其中的connectionFactory和destionation分别引用Spring中定义好的Bean。
3. Message Consumer
我们用一个简单的类来替代MDB。为了实现这个功能,我们需要考虑下面几个问题:
· 他需要实现MessageListener接口;
· 他需要监听一个Destination
· 系统启动的时候能够发布这个类
我们可以用下面的方法解决这些问题:
首先定义这个类:
public class MessageConsumerImpl implements MessageListener
{
public void init()
{
}
public void onMessage( Message message )
{
//process the message.
}
}
然后在Spring配置文件中定义这个Bean的时候,定义其init-method属性,如下:
<bean id="messageConsumer" class="com.company.MyMessageConsumer" init-method="init">
<property name="connectionFactory"><ref local="connectionFactory"/></property>
<property name="destination"><ref local="queue"/></property>
</bean>
在init方法中将该类和一个具体的Destination绑定,如下:
public void init() {
connection = (QueueConnection) connectionFactory.createConnection();
Session session = connection.createSession( false,
Session.AUTO_ACKNOWLEDGE );
MessageConsumer consumer = session.createConsumer( destination );
consumer.setMessageListener( this );
connection.start();
}
其中MessageCosumer是javax.jms包中的一个类。代码中仅用了一个Queue来作P2P的消息发送情况,Pub-Sub的消息没有测试。