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 注释之外,您的代码不依赖于 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();
}
}
控制台会显示
Hello, A Service
Hello, B Service
一句警告。API 文档指出,
“这样的服务定位器……通常用于原型 bean,即用于每次调用都应该返回一个新实例的工厂方法……对于单例 bean,直接注入目标 bean 的 setter 或构造函数是更可取的。 ”</p>
我不明白为什么这可能会导致问题。在我的代码中,它在对 serviceThatNeedsServiceInterface.useService() 的两次序列调用中返回相同的服务;
您可以在GitHub中找到我的示例的源代码