Nguồn Spring đã đề cập đến vấn đề của bạn khi họ tạo ra ServiceLocatorFactoryBean quay lại phiên bản 1.1.4. Để sử dụng nó, bạn cần phải thêm một giao diện tương tự như hình dưới đây:
public interface ServiceLocator {
//ServiceInterface service name is the one
//set by @Component
public ServiceInterface lookup(String serviceName);
}
Bạn cần phải thêm đoạn mã sau vào applicationContext.xml
<bean id="serviceLocatorFactoryBean"
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
<property name="serviceLocatorInterface"
value="org.haim.springframwork.stackoverflow.ServiceLocator" />
</bean>
của bạn Bây giờ ServiceThatNeedsServiceInterface của bạn sẽ trông giống như bên dưới:
@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 sẽ trả lại dịch vụ mong muốn dựa trên vòng loại RequestContext. Ngoài các chú giải mùa xuân, mã của bạn không phụ thuộc vào Mùa xuân. tôi thực hiện bài kiểm tra đơn vị sau đây cho trên
@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();
}
}
Giao diện điều khiển sẽ hiển thị
Xin chào, Một dịch vụ
Xin chào, B Dịch vụ
Một lời cảnh báo. Tài liệu API nêu rõ rằng
“Các trình định vị dịch vụ như vậy… thường sẽ được sử dụng cho các bean nguyên mẫu, nghĩa là các phương thức của nhà máy được cho là trả về một cá thể mới cho mỗi cuộc gọi… Đối với các hạt đơn, bộ đặt trực tiếp hoặc tiêm khởi tạo của bean mục tiêu thích hợp hơn. ”
Tôi không thể hiểu tại sao điều này có thể gây ra vấn đề. Trong mã của tôi, nó trả về cùng một dịch vụ trên hai cuộc gọi tuần tự tới serviceThatNeedsServiceInterface.useService();
Bạn có thể tìm thấy mã nguồn ví dụ của tôi trong GitHub
Bingo! Đây là câu trả lời chính xác. Tôi không ngại chút xíu về cấu hình XML. – Strelok