Spring从MQTT出站通道适配器获取事件

时间:2014-07-21 12:13:23

标签: java spring spring-mvc spring-integration mqtt

我已经在使用Spring Integration 4.1.0 SNAPSHOT。

我有这个MQTT出站适配器:

<int-mqtt:outbound-channel-adapter
        async="true"
        async-events="true"
        id="mqttOutput"
        channel="httpInputChannel"
        client-id="#{controller.mqttPublisherConfig.clientID}"
        url="#{controller.mqttPublisherConfig.completeURL}"
        default-qos="#{controller.mqttPublisherConfig.qosString}"
        default-retained="#{controller.mqttPublisherConfig.retainFlag}"
        default-topic="#{controller.mqttPublisherConfig.topic}"
        />

现在在我的Controller(MVC应用程序)中,我想接收适配器发出的事件。

我正在实施ApplicatinListener:

    @Controller
    public class ServletController implements ApplicationListener {

        public void onApplicationEvent(ApplicationEvent event)
        {
         //
        }

        ...
    }

仍然,我没有从MQTT适配器接收任何事件。

实现in-event:inbound-channel-adapter工作,但是:

<int-event:inbound-channel-adapter channel="eventLogger" 
                               error-channel="eventErrorChannel"
                               />

但我真的想处理代码中的事件!

1 个答案:

答案 0 :(得分:2)

您的@Controller与MQTT适配器位于同一应用程序上下文中吗?或者(最常见),控制器位于Web(DispatcherServlet)上下文中,其他bean位于ContextLoaderListener加载的根应用程序上下文中。

问题是根上下文中的bean无法“看到”servlet上下文中的bean,并且子上下文中的侦听器不会接收在根上下文中发布的事件。

您必须破坏此可见性问题 - 将业务bean移动到Web上下文中(通常不推荐,但对于小型应用程序并不可怕)或以某种方式将监听器从根上下文连接到控制器 - 也许通过布线它进入控制器并让控制器在初始化期间将自己传递给监听器(afterPropertiesSet())。你有一个类纠结(相互依赖),但它应该有效。

顺便说一下,ApplicationListener可以使用泛型

public class MyListener implements ApplicationListener<MqttIntegrationEvent> { ... }

只会获得MQTT事件。

编辑:

另一个解决方案是使用事件通道适配器并将outbound-channel-adapter添加到Web上下文(与控制器相同的上下文)...

@Controller
...

    public void onMqttEvent(MqttIntegrationEvent event) { ... }


<int:outbound-channel-adapter channel="eventLogger"
    ref="myController" method="onMqttEvent" />

它将在根上下文中显示通道。

务必将事件适配器配置为仅接收MqttIntegrationEvent s。