I have a Spring Web MVC application where i need to use an external device driver which returns information in an asynchronous manner every time the device gathers some new data. We need to pass an object at the begging to the start read method. This object implements an API defined interface which declares the callback method.
The problem raises when this callback method needs to manipulate some bean in Spring’s session scope. Because the callback gets called in the Thread of the driver when the callback implementation wants to access a Spring bean it yields an exception saying that the current thread is not in Spring’s managed scope.
I’m wondering if there’s any way to make the object which is implementing the callback interface into some kind of proxy which knows information about the context of the session which constructed it so this way it can invoke bean methods through Spring’s context object?
I think you are approaching the problem from the wrong side. I guess you want the device driver callback to put some results in the user session. But this is not enough to display that data, so (guessing again) probably some long-polling is involved, looking into the session through session-scoped bean.
With this assumption I advice you to generate some sort of unique
requestIdevery time you call the back-end driver and put thatrequestIdboth in the HTTP session and in the callback. When the callback is called, it pushes the results into some sort of map, where key is the assignedrequestId. Now the client (who knows therequestIdas well) can look into the map and fetch the results. You must remember about the synchronization (which is also the case with normalHttpSession).If you have some more advanced way of notifying clients (Comet? WebSockets?) this can also be done in this callback.
Note that technically you can pass an instance of
HttpSessionobject into the callback instance (but as you can see this does not work with Spring session-scoped beans) but passing session around doesn’t seem like a good design. It is simply better to provide a level of indirection. What if, in the future, you would like to reuse that code with command-line or desktop client?