67,549
社区成员




<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${jms.brokerURL}" />
<property name="userName" value="${jms.username}" />
<property name="password" value="${jms.password}" />
<property name="dispatchAsync" value="true" />
<property name="useAsyncSend" value="true" />
</bean>
<!-- 设置发送连接池,提高性能 -->
<bean id="JmsSenderFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory" ref="jmsFactory" />
<property name="maxConnections" value="100"></property>
</bean>
<!-- 设置接收连接池,提高性能 -->
<bean id="JmsReveiverFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="jmsFactory" />
<property name="maxConnections" value="100"></property>
</bean>
<!-- Spring JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsSenderFactory" />
<property name="defaultDestination" ref="destination" />
<!-- 区别它采用的模式:false是p2p;true是订阅 -->
<property name="pubSubDomain" value="false" />
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter" />
</property>
</bean>
<!-- Spring JMS Template -->
<bean id="jmsTemplate2" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsReveiverFactory" />
<property name="defaultDestination" ref="destination" />
<!-- 区别它采用的模式:false是p2p;true是订阅 -->
<property name="pubSubDomain" value="false" />
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter" />
</property>
</bean>
<!-- 发送消息的目的地(一个队列) -->
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字 -->
<constructor-arg index="0" value="${jms.queueName}" />
</bean>
<!-- 消息监听 -->
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="${jms.concurrentConsumers}" />
<property name="connectionFactory" ref="JmsReveiverFactory" />
<property name="destinationName" value="${jms.queueName}" />
<property name="messageListener" ref="messageConsumer" />
<property name="sessionTransacted" value="true"/>
<property name="pubSubNoLocal" value="true"></property>
</bean>
<!-- 消息消费者 -->
<bean id="messageConsumer"
class="com.voole.jms.MessageConsumer">
<property name="jmsTemplate2" ref="jmsTemplate2"></property>
</bean>
<!-- 消息生产 -->
<bean id="messageProducer"
class="com.voole.jms.MessageProducer">
<property name="jmsTemplate" ref="jmsTemplate"></property>
</bean>
</beans>
private static class MessageProbe {
private Object returnValue;
private CountDownLatch latch = new CountDownLatch(1);
public Object await() throws InterruptedException {
latch.await();
return returnValue;
}
public Object await(long timeout)
throws InterruptedException, TimeoutException {
boolean noTimeout = false;
noTimeout = latch.await(timeout, TimeUnit.MILLISECONDS);
if (noTimeout) {
return returnValue;
} else {
throw new TimeoutException("Response message timed out.");
}
}
public void obtainRetunValue(Object value) {
returnValue = value;
latch.countDown();
}
}
发出调用请求后我就生成一个"MessageProbe"的实例,然后交给之前生成的消费者.
我的每一次调用都会有一个唯一标识,就是根据这个标识来区分消费.
Map<String, MessageProbe> registerPool =
new ConcurrentHashMap<String, MessageProbe>();
一个简单的JDK5提供的Map实现,就能满足消费者持有这些"MessageProbe"实例的要求了.
接收到消息,查看自定义属性中的消息标识,根据这个标识找到"MessageProbe",然后调用"obtainRetunValue"方法为其注入消息.
调用线程只需要阻塞在MessageProbe.awit()方法上即可.