【问题标题】:Why does DefaultJmsListenerContainerFactory not expose setExceptionListener method?为什么 DefaultJmsListenerContainerFactory 不公开 setExceptionListener 方法?
【发布时间】:2019-05-07 10:16:56
【问题描述】:

我正在为使用DefaultJmsListenerContainerFactory 注册@JmsListener 注释方法的应用程序构建遥测和监控。

我已经为接收消息时引发的异常注册了一个错误处理程序,但我想注册一个类似的错误处理程序来监控我的应用程序与其订阅的主题之间的连接完整性。

我在AbstractMessageListenerContainter中发现了这个漂亮的setExceptionListener方法,但是DefaultJmsListenerContainerFactory没有提供设置这个属性的配置方法。

我搜索了 spring 框架 JMS javadocs,看看是否有任何关于为什么这个配置选项不存在的解释。有谁知道这不被曝光的原因吗?

【问题讨论】:

    标签: spring jms spring-jms


    【解决方案1】:

    看起来像是一个遗漏,或者被认为没有必要揭露。我建议你打开一个Improvement JIRA issue。

    与此同时,您可以从 JmsListenerEndpointRegistry 获取对容器的引用(使用 id),对其进行转换并设置属性。

    编辑

    这样的东西应该可以工作......

    @Bean
    public SmartInitializingSingleton lcPostProcessor(JmsListenerEndpointRegistry registry) {
        return () -> registry.getListenerContainers().forEach(c ->
                ((DefaultMessageListenerContainer) c).setExceptionListener(myExceptionListener()));
    }
    

    它在所有 bean 创建之后但在任何容器启动之前运行。

    【讨论】:

    • 谢谢!这有助于为我指明正确的方向。我已经在他们的待办事项中提交了一个改进问题,但在成为候选发布之前,您是否对 创建容器后如何执行此后处理有建议?
    • 您提出的解决方案无效。请查看我的回答,了解什么有效
    • 当然,当我尝试通过registry.getListenerContainers() 获取对它们的引用时,这些容器还不可用。抛出一个 NPE
    • 啊,是的,我的错;容器由另一个SmartInitializingSingleton 注册,该SmartInitializingSingleton 在此之后运行:( 好吧,至少我为您指明了正确的方向-虽然我可以理解您删除了“接受”,但删除赞成票似乎有点严重:)
    • 好点。我的错。我已经恢复了它,因为它确实为我指明了正确的方向。我的道歉
    【解决方案2】:

    这是最终让我可以访问此属性的原因。我测试了一下,我仍然可以像以前一样接收到该主题的消息

    public class PortalJmsListenerContainerFactory
            extends DefaultJmsListenerContainerFactory {
    
        private ExceptionListener exceptionListener;
    
        /**
         * @see DefaultMessageListenerContainer#setExceptionListener
         */
        public void setExceptionListener(ExceptionListener exceptionListener) {
            this.exceptionListener = exceptionListener;
        }
    
        @Override
        protected DefaultMessageListenerContainer createContainerInstance() {
            return new DefaultMessageListenerContainer();
        }
    
        @Override
        protected void initializeContainer(DefaultMessageListenerContainer container) {
            super.initializeContainer(container);
    
            if (this.exceptionListener != null) {
                container.setExceptionListener(this.exceptionListener);
            }
        }
    
    }
    

    【讨论】:

    • 很高兴听到@sachin1!
    • 感谢@andrewdleach 这非常有帮助,遇到了同样的问题。对于那些感兴趣的人,这是 2.x github.com/spring-projects/spring-boot/issues/22402 的目标。
    • 很高兴看到这一切即将到来!我完全忘记了我在他们的追踪器上放的那个问题
    猜你喜欢
    • 1970-01-01
    • 2014-08-29
    • 2011-02-17
    • 1970-01-01
    • 2011-01-04
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    相关资源
    最近更新 更多