使用Spring配置可以在运行时设置JMS侦听器目标

问题描述 投票:0回答:1

[我们在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>
java spring jms spring-jms
1个回答
0
投票

谢谢贾斯汀和加里成为橡皮鸭。阐明并发布我的配置可以帮助我找到答案,尽管可以对其进行优化。

我修改了监听器接口以包括

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>

从这里开始,为侦听器类的简单名称添加替代将是微不足道的

© www.soinside.com 2019 - 2024. All rights reserved.