java - 从不同的 HTTP 请求访问 Spring bean

标签 java spring spring-integration

感谢 Gary Russell 对我之前关于 SO 的问题的回答:Spring Integration manually start/stop channel adapter via control bus,我现在知道如何手动启动和停止 channel 适配器。

我的应用程序现在作为 servlet 在 tomcat 上运行。现在,除了启动该 channel 的请求之外,还有什么办法可以停止该 channel 的请求吗?我不确定范围问题,但在我看来,如果每个请求都在创建一个新网关,因此我从后面的请求发出“停止”命令,只会停止一个新实例,而这从未被停止过首先开始。还是我错了?

我的目标是创建一个 Restful Web 服务,它公开端点以通过 MQTT 发布/订阅/取消订阅,例如

http://someDomain/myModule/publishOverMQTT?topic=cloud&clientID=myClient&payload=myMsg
http://someDomain/myModule/subscribeOverMQTT&URL=someMQTTBrokerURL%clientID=myClient&topics=topic1,topic2,topic3

既然这是作为 servlet 部署的,那么如何实现“取消订阅”请求呢?根据我的理解,取消订阅是在 Spring Integration 中通过停止 channel 来完成的。 !但是!除了启动 channel 的请求之外,是否可以通过请求停止 channel ?

这是我的 context.xml:

<int:control-bus input-channel="controlChannel"/>

<int:gateway
    service-interface="MyGateway"
    default-request-channel="controlChannel"/>

<int-mqtt:message-driven-channel-adapter
    auto-startup="false"
    id="mqttInput" 
    client-id="#{controller.mqttSubscriberConfig.clientID}"
    url="#{controller.mqttSubscriberConfig.completeURL}"
    topics="#{controller.mqttSubscriberConfig.topic}"
    channel="loggingChannel" />

<int:logging-channel-adapter id="loggingChannel" />

按照下面加里·拉塞尔回答中建议的方式实现 HashMap ,我的 Controller 现在看起来像这样:

@RequestMapping("/subscribe")
public @ResponseBody void subscribe(
        @RequestParam(value="topics",   required=true) String topics,
        @RequestParam(value="clientID", required=true) String clientID,
        @RequestParam(value="url",      required=false) String url,
        @RequestParam(value="port",     required=false, defaultValue="1883") Integer port,
        HttpServletRequest request)
{
    mqttSubscriberConfig = new MQTTSubscriberConfiguration();
    mqttSubscriberConfig.setTopic(topics);
    mqttSubscriberConfig.setClientID(clientID);
    mqttSubscriberConfig.setURL(url);
    mqttSubscriberConfig.setPort(port);

    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
    ctx.getEnvironment().setActiveProfiles("sub");
    ctx.load("mqtt-context.xml");
    ctx.refresh();

    ((MyGateway)ctx.getBean(MyGateway.class)).control("@mqttInput.start()");

    ctxMap.put(clientID, ctx);
}

@RequestMapping("/unsubscribe")
public @ResponseBody void unsubscribe(
        @RequestParam(value="clientID", required=true) String clientID,
        HttpServletRequest request)
{
    GenericXmlApplicationContext ctx = ctxMap.get(clientID);
    ctx.destroy();
}

仍然,我有一种强烈的感觉,我不应该为每个请求创建上下文。对吗?

最佳答案

Spring Integration bean 没有请求范围;所有请求共享相同的 Spring Integration 基础设施。

不清楚“创建 HTTP 端点以开始/停止订阅”的含义。

关于java - 从不同的 HTTP 请求访问 Spring bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24683524/

相关文章:

java - 不幸的是,应用程序名称已在 Eclipse 中停止

java - 接收 String... 参数并将其值传递给接收 String ...参数的其他方法

Spring Data Elasticsearch 需要名为 id 的属性

spring - 从 Unix 读取而不使用 Spring Integration 复制到本地时发现循环引用

java - Vaadin EasyUpload 插件有时无法打开或找不到指定的文件

java.net.SocketTimeoutException : Read timed out exception while deploying app on Google App Engine

spring - 在 Kotlin Flow 中使用 ReactiveSecurityContextHolder

java - Hibernate Validator 注释不适用于 spring mvc

java - Spring 集成 : Calling event once certain sets of events have performed their task successfully.

java - Spring JMS ActiveMQ 跟踪作业状态