3

我是 JMS 的新手,需要批处理请求以供侦听器处理。链接:http ://sleeplessinslc.blogspot.in/2010/04/batchmessagelistenercontainer-using.html提供了一个很好的解决方案。我坚持执行相同的操作。我没有使用默认容器,而是重写了容器类以使用这个新类:

<jms:listener-container container-class="org.bsnyder.spring.jms.listener.BatchMessageListenerContainer"
       acknowledge="transacted">
    <jms:listener destination="CHANDRA.BATCHTEST" ref="messageListener" />
</jms:listener-container>

<bean id="messageListener" class="org.bsnyder.spring.jms.listener.BatchMessageListener" />

这里 BatchMessageListener 正在扩展博客中提到的 SessionAwareBatchMessageListener。

我得到的错误是:

[ERROR] PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'messageListener' threw exception; 
nested exception is java.lang.IllegalArgumentException: Message listener needs to be of type [org.bsnyder.spring.jms.listener.SessionAwareBatchMessageListener]: 
Failed properties: Property 'messageListener' threw exception; nested exception is java.lang.IllegalArgumentException: Message listener needs to be of type [org.bsnyder.spring.jms.listener.SessionAwareBatchMessageListener]

我应该更改容器类型(默认情况下是“默认”)吗?http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/jms.html不包含有关如何设置的详细信息。

4

2 回答 2

1

为什么需要从队列中批量读取消息?在这种情况下,我强烈建议您使用 spring batch 而不是编写自定义批处理侦听器。Spring批处理很容易配置。

于 2013-10-08T10:23:29.607 回答
1

问题是 jms 命名空间解析器正在使用引用您的实例org.springframework.jms.listener.adapter.MessageListenerAdapter的属性创建一个实例。因此,在您的方法中,您需要更改:delegateorg.bsnyder.spring.jms.listener.BatchMessageListenercheckMessageListener()BatchMessageListenerContainer

protected void checkMessageListener(Object messageListener) {
    if (!(messageListener instanceof SessionAwareBatchMessageListener)) {
        throw new IllegalArgumentException("Message listener needs to be of type ["
                + SessionAwareBatchMessageListener.class.getName() + "]");
    }
}

...对此:

protected void checkMessageListener(Object messageListener) {
    if (!(messageListener instanceof MessageListenerAdapter)) {
        throw new IllegalArgumentException("Message listener needs to be of type ["
                + MessageListenerAdapter.class.getName() + "]");
    }
}

虽然,在验证加载的类方面,这对你来说并没有什么好处。不幸的是,getDelegate()方法MessageListenerAdapter受到保护;否则,您可以检查委托的类型,这应该是您的 custom 实例SessionAwareBatchMessageListener。我想你可以使用反射。或者,您可以避免使用 jms 命名空间并创建自己的自定义BatchMessageListenerAdapter来实现SessionAwareBatchMesageListener和扩展MessageListenerAdapter,并使用该自定义适配器而不是 jms 命名空间的默认实现。(顺便说一句,没有办法覆盖这个默认值。)归根结底,它归结为你是否真的需要加载时验证。

如果您想跳过验证,只需执行以下操作:

protected void checkMessageListener(Object messageListener) {
    // Do nothing...
}

这将允许您的应用程序毫无问题地加载。

于 2013-10-07T15:31:04.067 回答