[我们在Spring应用程序中使用ActiveMQ,并且我正在根据定义发送数据的类名称设置使用虚拟主题的设计。因此,如果我有一个课程
public class SomeEvent implements JmsEvent<SomeEvent> {
...
}
其中JmsEvent
是用于将实现类转换为Message
的帮助程序接口,我还有另一个类,它将使用可配置的替代来确定目标名称
public class DestinationNameHelper {
private Map<Class<?>, String> overrides;
...
public String getDestinationName(Class<?> type) {
return overrides.getOrDefault(type, type.getSimpleName());
}
}
这对于JmsTemplate
效果很好,在此,每发送一条消息都会传递目的地名称。我有一个在结果前加上VirtualTopic.
的类,因此,如果您调用publisher.publish(someEvent)
,则发送SomeEvent
的实际目的地将是VirtualTopic.SomeEvent
。
我想做的是为侦听器使用相同类型的东西,所以如果有的话
public class SomeEventListener extends BaseMessageListener<SomeEvent> {
public void handleMessage(Message message) {}
}
我希望能够自动将其设置为侦听目标Consumer.SomeEventListener.VirtualTopic.SomeEvent
,该目标目前正在手动输入到XML配置文件中。使监听器类名称可重写会很好,但是我至少希望通过SomeEvent
检索虚拟主题名称(即DestinationNameHelper
),因此,如果我们重写a,则不必更改监听器配置类的目标名称。
例如如果将(SomeEvent.class, "OverrideName")
添加到DestinationNameHelper
中的覆盖图,则类别SomeEvent
的消息应发布在
VirtualTopic.OverrideName
听众应该听
Consumer.SomeEventListener.VirtualTopic.OverrideName
我无法弄清楚在XML配置中要执行此操作的SPEL方式,因为目标是使用JmsListenerConfigurer
基于类名来实现目标名可能超出范围。
有没有一种方法可以实现所需的配置?
[编辑]我的配置看起来像这样:
<bean id="someEventListenerBean" class="com.example.SomeEventListener"/>
<bean id="someEventListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="com.example.SomeEventListener"/>
</constructor-arg>
<property name="messageConverter">
<null/>
</property>
</bean>
<jms:listener-container connection-factory="jmsConnectionFactory" acknowledge="transacted" concurrency="2-5">
<jms:listener destination="Consumer.SomeEventListener.VirtualTopic.Somevent" ref="testListener"/>
</jms:listener-container>
谢谢贾斯汀和加里成为橡皮鸭。阐明并发布我的配置可以帮助我找到答案,尽管可以对其进行优化。
我修改了监听器接口以包括
Class<T> getEventType();
因此所有实现类都必须返回它们正在处理的类类型。然后,我创建了一个类似
的类public class ListenerDestinationHelper {
private final DestinationHelper destinationHelper;
public ListenerDestinationHelper(DestinationHelper destinationHelper) {
this.destinationHelper = destinationHelper;
}
public <E extends JmsEvent<E>, M extends Message, T extends JmsEventListener<E, M>> String getDestinationName(T listener) {
final Class<E> eventClass = listener.getEventType();
return "Consumer." + listener.getClass().getSimpleName() + ".VirtualTopic." + destinationNameFactory.getDestinationBaseName(eventClass);
}
}
并且现在配置包括
<bean id="listenerDestinationHelper" class="com.example.ListenerDestinationHelper"/>
<jms:listener-container connection-factory="jmsConnectionFactory" acknowledge="transacted" concurrency="2-5">
<jms:listener destination="#{listenerDestinationHelper.getDestinationName(someEventListenerBean)}" ref="testListener"/>
</jms:listener-container>
从这里开始,为侦听器类的简单名称添加替代将是微不足道的