1

I'm working on an Spring MVC 3.2 application deployed as an EAR with multiple web applications (WARS) that reuse many common data access and services beans, but can eventually provide a custom implementation for one or more services.

Basically each web application is a variation of a common solution, with different UI experience and different business rules in some services. These services are implemented as diverse stateless and stateful beans with dependencies between them.

The application has a parent-child structure of application contexts in place, so each web app has it's own context. An approximate idea is as follows:

-dao
  |-services
        |-one-app-context
               |-one-servlet-context
        |  
        |-two-app-context
               |-two-servlet-context

To build this, I have followed instructions given in:

http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/beans/factory/access/SingletonBeanFactoryLocator.html

I'm using XML config + annotation based bean scanning, with default shared singleton bean scope instantiation. There is a global properties file and each web app has its own properties files with new properties or variations on global properties - e.g. different values or strings. Also, all dependencies to services are made through interfaces.

My problem is that I'm forced to initialize a concrete implementation for each service to satisfy autowiring requirements when starting the shared context - but for a given web app, I'd like to use a different implementation or a new instance with different settings.

EDIT

@Prasad gave me a good practical reply - however I should have added the case where both controllers use the same implementation of a stateful service, but these are initialized with different settings/values - known only to each web layer package. I'd like to see a solution (if possible) where I use annotations/scanning and don't need to make instantiation acrobatics to get the right wiring - profiles perhaps?

In the end, dependencies would look somehow like this:

one-web-controller -> serviceA-impl-1
                   -> serviceB-impl -> serviceD-impl (with one.properties)
                   -> serviceC-impl
                   -> serviceE-impl (with one.properties)

two-web-controller -> serviceA-impl-2
                   -> serviceB-impl -> serviceD-impl (with two.properties)
                   -> serviceE-impl (with two.properties)

Keeping KISS in mind, how can I effectively setup Spring MVC so that each web app has its choice of custom service instances or implementations (or plugins, whatever you prefer) but at the same time maximize reuse?

Thanks for your help.

Reynaldo
  • 630
  • 1
  • 7
  • 19

1 Answers1

1

Assuming you are implementing service layer in parent context hierarchical form (check for implementing parent, root and child contexts in this answer given by me), the service implementations can be injected using qualifiers.

For example you have an interface:

    public interface ServiceA {
        public void yourMethod();
    }

and its implementation classes as:

    @Component(value="serviceAImpl1")
    public class ServiceAImpl1 implements ServiceA {

    }

    @Component(value="serviceAImpl2")
    public class ServiceAImpl2 implements ServiceA{

    }

In web app 1, if you want to access ServiceAImpl1, you can get it as:

    @Component
    public class WebApp1Class {
      @Autowire
      @Qualifier("serviceAImpl1")
      ServiceA serviceA;
      ...
    }

In web app 2, if you want to access ServiceAImpl2, you can get it as:

    @Component
    public class WebApp2Class {
      @Autowire
      @Qualifier("serviceAImpl2")
      ServiceA serviceA;
      ...
    }
Community
  • 1
  • 1
Prasad
  • 3,785
  • 2
  • 14
  • 23
  • this solves the issue with custom implementations - but I've edited my question to show a case where e.g. ServiceAImpl1 depends on a stateful ServiceBImpl1 with some settings and serviceAImpl2 also depends on same ServiceBImpl1, however with different settings. – Reynaldo Apr 16 '14 at 16:14