Announcement Announcement Module
No announcement yet.
outbound-channel-adapter for prototype beans Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • outbound-channel-adapter for prototype beans

    I need to dynamically create POJOs that plug into a set of spring integration channels that I have configured in my application context. Some of the singleton POJOs have been configured to receive messages from various sources. Some messages indicate that a new service object should be dynamically created and plugged into the graph. The new service objects will observe various phenomena and stream a set of update messages into the channels in order to get their observations to a destination.

    I see that int:inbound-channel-adapter with a poller can take a singleton POJO and do what I want. But the configuration works for the singleton beans. Is there any way to use the XML configuration for prototype beans?

    Or should I define my own factory bean and configure everything in a standard spring factory bean, essentially duplicating what the XML configuration does for me?

  • #2
    Can you explain your use case so that we can understand your requirement better?


    • #3
      I have an POJO that needs to receive requests from several sources, such as a queue, or a web service call. I put this object, the spawner, inside a spring integration graph. The spawner has been wired up to receive these requests. The request object tells the spawner to start up a specific type of "sensor." The sensor needs to be created and wired into the graph so it can send update messages and have those messages routed the right destination for reporting. The network for the spawner and the sensors is known ahead of time so I can configure the graph so that it connects to the external world okay and it knows how to route update messages.

      But I need to dynamically spawn new sensors based on the request. The sensor objects should not have any knowledge of the graph, it just produces update messages that can be read by a poller, etc. The sensors will need to run in their own thread.

      The xml configuration model for spring-integration seems to focus on creating a well-known, singleton graph topology. I need to have something more dynamic. When the sensor object is created, I also have to create the wrappers around it becomes a message producer with a poller and is sending updates to the right channel. The sensor eventually finishes and terminates itself.

      Can I do this in XML completely? Or do I need to write a clever factory bean and plug the factory bean into a ServiceLocatoryFactoryBean in my POJO so that everything can be configured my bean definition file.

      On a related issue, since the sensor runs in its own thread (I have the callable interface under it), I set up the sensor to autosubmit itself to an executor but I have not figured out how to actually start running it i.e. invoke the call() interface with causing a thread join in the calling thread. The output of the call() is itself a message that I need to poll for and route into the graph.

      interface Sensor extends Callable<FinalResult> {
         UpdateObject getNextUpdate();
      I need to wire up both methods to get those results into the graph. Sensor must run in its own thread so it do its sensing thing.


      • #4
        Since starting a new spawner based on some condition is a classic IF statement and in EIP terms is the classic Router, why not have all spawners available and route to the appropriate one based on the request?


        • #5
          Its not the spawners that are the issue for me. I actually really only need 1 spawner who listens for requests. There are several types of sensors that must be dedicated to observing one part of the external environment. I am expecting about 1K sensors to be active at any given time each one observing something different but reporting updates and end status back to the graph and eventually, routed externally to a dashboard.

          Its the object that is spawned (the sensor) when the request comes in. The sensor that is spawned must:

          0) Be created with opportunities for dependency injection.
          a) Run in its own thread. It needs to kickstart itself with an executor.
          b) Emit frequent update requests that must be routed into the channels so it is "published" to the right external system.
          c) Emit a final status object that must be routed into the channels so it is "published" to the right external system.
          d) Shut itself down. It will shut itself down once it has finished observing what it was spawned to observe. It also needs to disconnect itself from the channel.

          So ideally I would define an XMLprototype for each type of spawned sensor. I could write a factory to find the right prototype to spawn. But the namespace XML model of defining the channels and objects in the container do not seem to support prototype beans. To make my sensor independent of all the spring components, I have to attached it to a channel adapter, with a poller, and a channel.

          My spawner just needs to know to call a factory (say ServiceLocatoryFactoryBean) to obtain a new sensor that is automatically configured into the graph already.

          I have a feeling that I cannot define the sensor part of my app directly through namespace XML integ: support since the namespace XML support focuses on singletons.


          • #6
            So why not have SpawnerFactoryBean and wire it with service-activator
            Something like this:
            public class SpawnerFactoryBean implements FactoryBean {
                    public void spawne(Message<?> message) {
                        . . . 
                        // your code, will probably set some instance variables so the getObject() call returns the appropriate spawner
                        // may need to be synchronized
                        Spawner sp = this.getObject()
            Why do they have to be prototypes if each spawner bean is different?


            • #7
              Its not the spawner that causes me the problem. The uniqueness is at the sensor level. There are about 10 different sensor types. Those are the prototypes. The single spawner receives a message that says "spawn a sensor of type X and start it up." The spawner has a factory member which I configure in spring through ServiceLocatorFactoryBean so that I can configure the factory, and hence the sensor prototype, purely in spring. Very nice.

              It may be that you are saying that I should create a spawner for each sensor type, however, I still have to create the sensors dynamically and attach them.

              Based on the idea of the factory bean, and the only way I see to do it, is to create a SensorFactoryBean. Then in the createInstance method:

              		Sensor obj = (Sensor) applicationContext
              		// Wire the update events
              		SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
              		MethodInvokingMessageSource source = new MethodInvokingMessageSource();
              		adapter.setTrigger(new PeriodicTrigger(updatePeriod));
              		if (taskExecutor != null)
              		return obj;
              I think that will work. The spawner performs some additional services so creating the factory bean at the sensor level is probably the right way to go (I'd also like to keep that spring free for other reasons).


              • #8
                It's not entirely clear to me what you are trying to do, but the dynamic-ftp sample (in advanced samples) here uses a technique to dynamically create Spring Integration flow snippets as new application contexts.

                If the snippet needs resources (beans) from the main context, just make the main context the parent of the snippet's context and then the snippet can reference beans in the parent context (but not vice-versa); they can, however, exchange messages as shown in that sample.


                • #9
                  As an update, I eventually realized that for my service objects, which are dynamically created and need to be wired into the graph, instead of a FactoryBean to create the service (there are several types of service types so the factory bean seemed inflexible for this) that all I really needed to do was define a "sensor scope" that when it is asked to create a sensor object, validates its type then wraps it in an outbound adapter and method invoking message source. The destruction callback allows me to keep a small amount of state in a callback that unplugs the sensor from the graph once it determines to stop sensing on its own.

                  So if the graph is not static and you need to dynamically create objects over a long period of time that send update events to the graph to be routed somewhere, a "scope" seemed like the best solution.