Java – customizing autowire candidate beans in spring 3

I have a service interface serviceinterface and the following structures of some components that implement it: productaservice and productbservice. I also have a requestcontext bean, which has a qualified attribute, indicating that we are processing ProductA or productb Then, how to automatically inject the correct implementation of auto assembly or other annotations (productaservice or productbservice) to some services that need it (under service that needs service interface)

public interface ServiceInterface {
  void someMethod();
}

@Component(name="ProductAService")
public class ProductAService implements ServiceInterface {
  @Override public void someMethod() { 
    System.out.println("Hello,A Service"); 
  }
}

@Component(name="ProductBService")
public class ProductBService implements ServiceInterface {
  @Override public void someMethod() { 
    System.out.println("Hello,B Service"); 
  }
}

@Component
public class ServiceThatNeedsServiceInterface {

  // What to do here???
  @Autowired
  ServiceInterface service;

  public void useService() {
    service.someMethod();
  }
}

@Component
@Scope( value = WebApplicationContext.SCOPE_REQUEST )
public class RequestContext {
  String getSomeQualifierproperty();
}

Solution

Spring source is in version 1.1 Your problem was referenced when creating servicelocatorfactorybean in 4 In order to use it, you need to add an interface similar to the following:

public interface ServiceLocator {
    //ServiceInterface service name is the one 
      //set by @Component
    public ServiceInterface lookup(String serviceName);
}

You need to add the following code snippet to your ApplicationContext In XML

<bean id="serviceLocatorfactorybean"
    class="org.springframework.beans.factory.config.ServiceLocatorfactorybean">
    <property name="serviceLocatorInterface"
              value="org.haim.springframwork.stackoverflow.ServiceLocator" />
</bean>

Now your servicethatneedsserviceinterface will look like the following:

@Component
public class ServiceThatNeedsServiceInterface {
    // What to do here???
    //  @Autowired
    //  ServiceInterface service;

    /*
     * ServiceLocator lookup returns the desired implementation
     * (ProductAService or ProductBService) 
     */ 
 @Autowired
     private ServiceLocator serviceLocatorfactorybean;

     //Let’s assume we got this from the web request 
     public RequestContext context;

     public void useService() {
        ServiceInterface service =  
        serviceLocatorfactorybean.lookup(context.getQualifier());
        service.someMethod();         
      }
}

Servicelocatorfactorybean will return the required service according to the requestcontext qualifier Except for spring annotations, your code doesn't depend on spring I performed the above unit tests

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:Meta-INF/spring/applicationContext.xml" })
public class ServiceThatNeedsServiceInterfaceTest {

    @Autowired
    ServiceThatNeedsServiceInterface serviceThatNeedsServiceInterface;

    @Test
    public void testUseService() {
    //As we are not running from a web container
    //so we set the context directly to the service 
        RequestContext context = new RequestContext();
        context.setQualifier("ProductAService");
        serviceThatNeedsServiceInterface.context = context;
        serviceThatNeedsServiceInterface.useService();

        context.setQualifier("ProductBService");
        serviceThatNeedsServiceInterface.context = context;
        serviceThatNeedsServiceInterface.useService();
    }

}

Display console Hello, a service Hello, B service

A warning The API document states that "such a service locator... Is usually used for prototype beans, that is, the factory method that returns a new instance for each call. For singleton beans, it is better to directly inject the setter or constructor into the target bean

I don't understand why it caused a problem In my code, it returns the same service and calls servicethatneedsserviceinterface in two sequences useService();

You can find the source code for my example in GitHub

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>