Accessing Spring bean from different HTTP request

痴心易碎 提交于 2019-12-11 19:04:31

问题


I now know how to manually start and stop a channel adapter thanks to Gary Russells answer to my previous question on SO: Spring Integration manually start/stop channel adapter via control bus

My application is now running as a servlet on a tomcat. Now, is there anyway to stop a channel from a request other than the request that started this channel? I am not sure about the scope issue, but it seemes to me, like if each request is creating a new gateway, and therefore me issuing a "stop" command from a later request, would only stop a new instance, that had never been started in the first place. Or am I wrong?

My objective is to create a restful web service, which exposes endpoints to publish / subscribe / unsubscribe over MQTT, e.g.

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

Now since this is deployed as a servlet, how is it possible to implement an "unsubscribe" request? In my understanding, unsubscribing is done in Spring Integration by stopping the channel. !BUT! Is it possible to stop a channel from a request, other than the request that started it?

This is my 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" />

Implementing a hashmap like suggested in Gary Russells answer below, my controller now looks something like this:

@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();
}

STILL, I have a strong feeling, that I should not be creating a context for each request. Right?


回答1:


There is no request scope for Spring Integration beans; all requests share the same Spring Integration Infrastructure.

It's not clear what you mean by "create HTTP endpoints to start/stop subscribing".



来源:https://stackoverflow.com/questions/24683524/accessing-spring-bean-from-different-http-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!