加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 在Spring 3中定制Autowire候选bean

发布时间:2020-12-14 17:43:09 所属栏目:Java 来源:网络整理
导读:说我有一个服务接口ServiceInterface和一些实现它的组件的以下结构:ProductAService和ProductBService我还有一个RequestContext bean,它有一个限定属性,表示我们现在正在处理ProductA或ProductB.那么如何可以自动注入自动装配或其他注释正确的实现(ProductA
说我有一个服务接口ServiceInterface和一些实现它的组件的以下结构:ProductAService和ProductBService我还有一个RequestContext bean,它有一个限定属性,表示我们现在正在处理ProductA或ProductB.那么如何可以自动注入自动装配或其他注释正确的实现(ProductAService或ProductBService)到某些需要它的服务(ServiceThatNeedsServiceInterface下面).
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();
}

解决方法

Spring Source在版本1.1.4中创建了 ServiceLocatorFactoryBean时引用了您的问题.为了使用它,您需要添加类似于下面的界面:
public interface ServiceLocator {
    //ServiceInterface service name is the one 
      //set by @Component
    public ServiceInterface lookup(String serviceName);
}

您需要将以下代码片段添加到您的applicationContext.xml中

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

现在您的ServiceThatNeedsServiceInterface将类似于以下内容:

@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将根据RequestContext限定符返回所需的服务.
除了弹簧注释,你的代码不依赖于Spring.
我执行了以上的单元测试

@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();
    }

}

显示控制台
你好,一个服务
你好,B服务

一句警告. API文档说明
“这样的服务定位器…通常将用于原型bean,即对于每个调用返回一个新实例的工厂方法,对于单例bean,最好是直接设置器或构造器注入目标bean.

我不明白为什么会导致一个问题.在我的代码中,它返回相同的服务在两个序列调用serviceThatNeedsServiceInterface.useService();

您可以在GitHub中找到我示例的源代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读