这就是我动态创建新的Listener
并让Spring处理关闭过程 的方法
<beans>
//other beans
<bean id="importReadQueueDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>queue/dummyQueue</value></property>
<property name="resourceRef"><value>true</value></property>
</bean>
<bean id="importQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>ConnectionFactory</value></property>
<property name="resourceRef"><value>true</value></property>
</bean>
<bean id="importReadQueueSenderService" class="com.localhost.ImportReadQueueSenderService" scope="prototype"/>
<!-- this is the Message Driven POJO (MDP) -->
<bean id="importReadMessageListener" class="com.localhost.listener.ImportReadMessageListener" scope="prototype"/>
<!-- and this is the message listener container -->
<bean id="importReadJmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" scope="prototype">
<property name="connectionFactory" ref="importQueueConnectionFactory" />
<property name="destination" ref="importReadQueueDestination" />
<property name="messageListener" ref="importReadMessageListener" />
<property name="concurrentConsumers" value="1"/>
</bean>
</beans>
在这里,我创建了一个虚拟队列queue/dummyQueue
,因为 DMLC 需要设置destination
ordestinationName
属性。
ImportReadMessageListener
扩展 MessageListener。用于创建和缓存动态侦听器的 Java 代码
//Actual queue name where I need to send message. `tenantStore` is obtained from ThreadLocalObject
String queue = tenantStore.getProperty("importReadQueue");
//Obtaining existing senderService for that queue
Object queueSenderService = AppConfigurationManager.getQueueSenderService(queue);
if (queueSenderService != null) {
((IImportReadQueueSenderService) queueSenderService).sendObjectMessage(importReadQueueDO);
} else {
// In-case of call received from new tenant, then dynamically create and cache a separate listener and DMLC for it
InitialContext ic = new InitialContext();
Queue destination = (Queue) ic.lookup(queue);
ConnectionFactory importQueueConnectionFactory =(ConnectionFactory) ServiceContext.getBean("importQueueConnectionFactory");
JmsTemplate importJmsTemplate=new JmsTemplate(importQueueConnectionFactory);
importJmsTemplate.setDefaultDestination(destination);
Object importReadMessageListener = ServiceContext.getBean("importReadMessageListener");
DefaultMessageListenerContainer dmlc = (DefaultMessageListenerContainer)ServiceContext.getBean("importReadJmsContainer");
dmlc.setDestination(destination);
/* below two steps are extremely important else you won't receive any message.
I already wasted a day behind this.*/
// https://stackoverflow.com/a/21364885/4800126
dmlc.afterPropertiesSet();
dmlc.start();
IImportReadQueueSenderService importQueueSenderService = (IImportReadQueueSenderService) ServiceContext
.getBean("importReadQueueSenderService");
AppConfigurationManager.cacheQueueDetails(queue, dmlc, importQueueSenderService,
importReadMessageListener);
importQueueSenderService.setJmsTemplate(importJmsTemplate);
importQueueSenderService.sendObjectMessage(importReadQueueDO);
}
所以现在当你关闭应用程序时,Spring 会自动关闭所有的监听器。