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

前端之家收集整理的这篇文章主要介绍了java – 在Spring 3中定制Autowire候选bean前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
说我有一个服务接口ServiceInterface和一些实现它的组件的以下结构:ProductAService和ProductBService我还有一个RequestContext bean,它有一个限定属性,表示我们现在正在处理ProductA或ProductB.那么如何可以自动注入自动装配或其他注释正确的实现(ProductAService或ProductBService)到某些需要它的服务(ServiceThatNeedsServiceInterface下面).
  1. public interface ServiceInterface {
  2. void someMethod();
  3. }
  4.  
  5. @Component(name="ProductAService")
  6. public class ProductAService implements ServiceInterface {
  7. @Override public void someMethod() {
  8. System.out.println("Hello,A Service");
  9. }
  10. }
  11.  
  12. @Component(name="ProductBService")
  13. public class ProductBService implements ServiceInterface {
  14. @Override public void someMethod() {
  15. System.out.println("Hello,B Service");
  16. }
  17. }
  18.  
  19. @Component
  20. public class ServiceThatNeedsServiceInterface {
  21.  
  22. // What to do here???
  23. @Autowired
  24. ServiceInterface service;
  25.  
  26. public void useService() {
  27. service.someMethod();
  28. }
  29. }
  30.  
  31. @Component
  32. @Scope( value = WebApplicationContext.SCOPE_REQUEST )
  33. public class RequestContext {
  34. String getSomeQualifierProperty();
  35. }

解决方法

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

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

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

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

  1. @Component
  2. public class ServiceThatNeedsServiceInterface {
  3. // What to do here???
  4. // @Autowired
  5. // ServiceInterface service;
  6.  
  7. /*
  8. * ServiceLocator lookup returns the desired implementation
  9. * (ProductAService or ProductBService)
  10. */
  11. @Autowired
  12. private ServiceLocator serviceLocatorfactorybean;
  13.  
  14. //Let’s assume we got this from the web request
  15. public RequestContext context;
  16.  
  17. public void useService() {
  18. ServiceInterface service =
  19. serviceLocatorfactorybean.lookup(context.getQualifier());
  20. service.someMethod();
  21. }
  22. }

ServiceLocatorfactorybean将根据RequestContext限定符返回所需的服务.
除了弹簧注释,你的代码不依赖于Spring.
我执行了以上的单元测试

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = { "classpath:Meta-INF/spring/applicationContext.xml" })
  3. public class ServiceThatNeedsServiceInterfaceTest {
  4.  
  5. @Autowired
  6. ServiceThatNeedsServiceInterface serviceThatNeedsServiceInterface;
  7.  
  8. @Test
  9. public void testUseService() {
  10. //As we are not running from a web container
  11. //so we set the context directly to the service
  12. RequestContext context = new RequestContext();
  13. context.setQualifier("ProductAService");
  14. serviceThatNeedsServiceInterface.context = context;
  15. serviceThatNeedsServiceInterface.useService();
  16.  
  17. context.setQualifier("ProductBService");
  18. serviceThatNeedsServiceInterface.context = context;
  19. serviceThatNeedsServiceInterface.useService();
  20. }
  21.  
  22. }

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

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

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

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

猜你在找的Java相关文章