Announcement Announcement Module
Collapse
No announcement yet.
Configuration of proxy bean with map + RUNTIME target select Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Configuration of proxy bean with map + RUNTIME target select

    Hi all,

    I am currently evaluating Spring and its potential benefits for J2EE application development here at INFOSYS in Bangalore.

    We currently have one application that uses a component to determine and load the to-be-used service implementation for a service (depending on a RUNTIME parameter) and run the service with this implementation then in the next step.

    BASIC GOAL: I would like to replace this component, i.e. use Spring configuration to set-up runtime target selection for the service implementation depending on a runtime parameter.

    --> This seems not to be feasible with Spring out of the box!?

    --> Idea: is there maybe something like proxy bean (used as placeholder for concrete serviceImpl) where the target can be selected a runtime from a map/"directory of targets" and the map/"directory" could be set-up like this:

    key [customer-type-individual] --> target [serviceImplCustomerIndividual] (bean-ref to existing spring bean definition)
    key [customer-type-business] --> target [serviceImplCustomerBusiness] (bean-ref to existing spring bean definition)

    ...Detailed Example [if not clear what I mean yet]:

    [BUSINESS GOAL]: determine credit rating for specific customer
    [ACHIEVED WITH]: CreditRatingService component/bean (has a property 'serviceImpl' holding the to-be-used & customer type-specific serviceImpl to calculate the credit rating)
    [PARAMETER (at RUNTIME!)]: type of customer (business|individual) as string
    [ACTIONS]:
    [1] load customer-specific implemenation into service.serviceImpl bean property
    [2] execute calculation: service.doCalc (using the service.serviceImpl that has been loaded dynamically)

    I would like to replace the repeated lookup code which is currrently in place and which in general uses java reflection api for the serviceImpl selection using Spring configuration concepts.... goal: select target serviceImpl bean that has already been defined in Spring config.

    Problem: the biggest hurdle seems to be to select the component at RUNTIME (and not configuration time) depending on the RUNTIME parameter (customer type) [this simply seems not to be feasible in using available Spring configuration means.

    I did try the following:

    [1 - "ugly"] Use AOP beforeMethod advice on "service.doCalc(String customerType)" to load correct serviceImpl before "service.doCalc()" executes depending on parameter 'customerType'
    [...finding 1] does not replace lookup-component but simply wraps it into AOP advice and therefore does not get rid of reflection use
    [...finding 2] reflection use could only be replaced by hard-coded selection of the appropriate service implementation (inject appropriate serviceImpl MANUALLY into service from a set reference from a set of given bean-refs to serviceImpls available in advice)

    [2] read through bean factory interface documentation (idea: implement new factory type)
    [...finding] getObject() does not support to pass in a parameter upon which the concrete instance (implementing the serviceImpl interface) could be returned --> not usable for my goal

    Thanks for any ideas on this!

    Michael

  • #2
    Check this topic:

    http://forum.springframework.org/showthread.php?t=18640

    The user had the same problem. He wanted to create a Command based on runtime and compiletime parameters (the standard spring parameters). This can be solved by creating a standard factory:

    Code:
    interface Service{
         int calc(Person p);
    }
    
    class ServiceFactory{
    
            private Service tiny,medium,gozilla;
    
           public ServiceFactory(Service tiny,Service medium, Service godzilla){
                 _tiny= tiny;
                 _medium = medium;
                 _godzilla = godzilla;       
           }
    
          Service create(int age,....){
                if(age<10)return _tiny;
                if(age<50)return _medium;
                return _godzilla;
          }
    }
    In this case the Service is selected on a age value.

    And if someone needs a Service, it can just call:

    Service service = serviceFactory.create(person.getAge());
    int value = service.calc(person);

    (the dependency to the serviceFactory has to be injected into that class, but that shouldn`t be any problem).

    If you need security/transactions on the services it would be no problem. All the services can be created in Spring and injected into the ServiceFactory. Maybe ServiceFactory could be renamed to ServiceSelector (because it doesn`t construct anything anymore).
    Last edited by robyn; May 14th, 2006, 07:02 PM.

    Comment


    • #3
      Hi, thanks for the quick reply.

      Okay,... basically I could roll with this.

      But this is one additional bean that I have to implement per serviceImpl interface (besides some map config for the serviceImpl selector/factory).

      ...I would then be able to leverage from IoC,... but is this not a bit of overhead for a "standard" problem?

      As mentioned: I did read through the factoryBean stuff and also (hotswapping)target sources, but this really does not cater my needs [if I do not want to do addtl. AOP stuff - in the latter case].

      Therefore: is there maybe some more standard solution to this (like proxy bean with a "routing" map to forward me to the correct serviceImpl prototype bean)?

      Cheers, Michael

      Comment


      • #4
        Originally posted by mschiffe
        Hi, thanks for the quick reply.

        Okay,... basically I could roll with this.

        But this is one additional bean that I have to implement per serviceImpl interface (besides some map config for the serviceImpl selector/factory).
        Yes. But how many services do you have that are 'switchable'.

        ...I would then be able to leverage from IoC,... but is this not a bit of overhead for a "standard" problem?
        This is the easiest to understand I think. If I examine the rest of your reply, I see so much more complexity: proxies, aop, hotswapping.

        Therefore: is there maybe some more standard solution to this (like proxy bean with a "routing" map to forward me to the correct serviceImpl prototype bean)?
        In essence the Selector/Factory bean is doing that. If you need more control on the routing, you can register service with some predicate. If the predicate holds, the service can be retourned. I use the same technique for my routing channels and it works like a charm.

        Comment


        • #5
          Michael, I think you are on the right track. If you are only talking about three or four components here, then you are probably better off with the factory solution that Alarmnummer suggests. (What does Alarmnummer mean? Is that a Dutch word?)

          If this is something that is used pervasively through the application (and I can identify, I have a very similar situation at my current assignment), then you will want to build an intelligent interceptor that can locate the correct directory of targets, and then select the appropriate target depending on the input parameter. Now you only have to build one interceptor, although you will have to proxy all of your services in the configuration files.

          Assuming no repeated data access is needed to load your directory of targets, performance should be just fine.

          Comment


          • #6
            Originally posted by cepage
            Michael, I think you are on the right track. If you are only talking about three or four components here, then you are probably better off with the factory solution that Alarmnummer suggests. (What does Alarmnummer mean? Is that a Dutch word?)
            Yes... it means: emergency number (911)

            Comment


            • #7
              cepage,

              yupp,... I think we are almost on the same page:

              you will want to build an intelligent interceptor that can locate the correct directory of targets, and then select the appropriate target depending on the input parameter. Now you only have to build one interceptor, although you will have to proxy all of your services in the configuration files.
              I basically would like to use such a redirector/impl selector component also for crossing the different layers in my application architecture,... for example:

              [presentation layer]
              *** use redirector/impl selector to select the appropriate business layer service bean depending on runtime criteria ***
              [business layer]
              *** use redirector/impl selector to select the appropriate data layer service bean depending on runtime criteria ***
              [data layer]

              With the factory approach I can do the selection... but since I will have many modules/functions with potentially different calling interfaces for the next layer services I possibly will have many of these factories (one per module interface & layer) around.

              So the idea is really to do this with a generically working interceptor bound to the respective classes once / employing AOP. This might mean just one additional interceptor adivce coding but not to implement too much factories to do the job.

              --> @CEPAGE: do you maybe have a solution / more detailed approach description for this on hand?

              Thanks for your thoughts so far & in advance!

              Comment


              • #8
                Originally posted by mschiffe
                So the idea is really to do this with a generically working interceptor bound to the respective classes once / employing AOP.
                From your original question, I understood you to have an existing directory/map of targets for each of your service-layer modules. If that is the case, then you are almost done. You just need to inject the directory into your interceptor, and allow the interceptor to select the correct one and proceed from there.

                If you do not have an existing directory, you are going to have to build it on startup, and that will probably be the bulk of your work. There are alternatives. For example, at my current assignment the service layer modules use very strict package/naming conventions, so that it is possible for me to dynamically construct the correct classname depending on the input parameters.

                One other piece of advice: think for a while about the exceptions that your interceptor can throw, and make sure that it throws very clearly documented exceptions if anything goes wrong. This will make it a lot easier for other developers to maintain, since they may not be used to this sort of programming model.

                Comment


                • #9
                  ServiceLocatorFactpryBean - can this be of help in this issu

                  How can this help me with my issue?
                  http://www.springframework.org/docs/...ctoryBean.html

                  [not at all/to a certain part? --> can you give an example for using servicelocatorfactorybean]

                  Comment


                  • #10
                    Re: ServiceLocatorFactpryBean - can this be of help in this

                    Originally posted by mschiffe
                    How can this help me with my issue?
                    http://www.springframework.org/docs/...ctoryBean.html

                    [not at all/to a certain part? --> can you give an example for using servicelocatorfactorybean]
                    ServiceLocatorFactoryBean is great, but it requires you to create a separate factory method implementation for each of your components. Earlier in this thread, you indicated that was unacceptable for your requirements.

                    Comment

                    Working...
                    X