如何使用 Spring 配置文件模拟实现相同接口的不同服务
How to use Spring profiles to mock different services that implement the same interface
我有以下场景:
我有一个 Springboot 微服务,它可以收集来自不同提供商(外部 SOAP 网络服务)的产品列表。我们目前从 2 个供应商处获取信息,例如 Amazon 和 EBay。
但将来我可以有更多的提供者,所以我的应用程序需要具有可扩展性。
此外,我可以从 Amazon 或 Ebay 收集信息,也可以从这两种服务获取信息,如果提供商列表增加,例如,我可以添加全球速卖通,我应该可以选择 Amazon + AliExpress 或 Ebay + AliExpress 或三者。
我创建了一个接口:
public interface ProductsService {
List<Product> getProducts();
}
以及实现此接口的classes:
public class AmazonProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Amazon Products
}
}
public class EbayProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Ebay Products
}
}
到目前为止,我设法让它们工作,我还有一些适配器 classes 从服务获取信息并将它们调整为我定义的 POJO。
问题来了,因为我需要提供一种机制来模拟每个不同的服务。我的意思是,我需要为亚马逊、Ebay 和我的 Spring 启动应用程序需要联系的每个供应商创建一个模拟。
在另一个项目中,我使用了 Spring 配置文件,这很有用,因为我能够定义一个 "mock" 配置文件,但在那种情况下,我只有一项服务,在这种情况下,我有很多其中实现了相同的接口。
到目前为止,我尝试的是:
public class MockAmazonProductsService implements ProductsService {
public List<Product> getProducts() {
return new ArrayList<Product>();
}
}
我也创建了它的配置:
@Configuration
@Profile("mockamazon")
public class MockAmazonProductsServiceAutoconfiguration {
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
}
我为 Ebay 服务做了同样的事情(配置文件是 "mockebay")。
我的问题是,设置配置文件后如何调用模拟服务,例如:
spring.profiles.active=mockamazon
在模拟的要求之前我有以下 class:
@Service
public class ProductsServiceFactory {
@Autowired
@Qualifier("AmazonProductsService")
private ProductsService amazonProductsService;
@Autowired
@Qualifier("EbayProductsService")
private ProductsService ebayProductsService;
public List<ProductsService> getProductsService(String selectedServicesParameter) {
String[] selectedServices = selectedServicesParameter.split(",");
List<ProductsService> servicesList = new ArrayList<>();
for (String selectedService : selectedServices) {
if (selectedService.equals("AMAZON") {
servicesList.add(amazonProductsService);
} else if (selectedService.equals("EBAY") {
servicesList.add(ebayProductsService);
}
}
return servicesList;
}
}
但是现在,我不确定如何调用模拟服务。我想为模拟服务创建一个额外的服务工厂,但我可能会遇到只需要模拟一个服务而不是所有服务的场景。
如有任何建议,我们将不胜感激。
我不能说我的解决方案是完美的,但它确实有效。
您可以为每个案例创建配置文件并进行配置:
@Configuration
public class MockServiceAutoconfiguration {
@Profile({"mockAmazon", "mockAll", "mockAmazonAndEbay"})
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
@Profile({"mockAliexpress", "mockAll"})
@Bean
public ProductsService aliexpressProductsService() {
return new MockAliexpressProductsService();
}
}
我有以下场景:
我有一个 Springboot 微服务,它可以收集来自不同提供商(外部 SOAP 网络服务)的产品列表。我们目前从 2 个供应商处获取信息,例如 Amazon 和 EBay。
但将来我可以有更多的提供者,所以我的应用程序需要具有可扩展性。
此外,我可以从 Amazon 或 Ebay 收集信息,也可以从这两种服务获取信息,如果提供商列表增加,例如,我可以添加全球速卖通,我应该可以选择 Amazon + AliExpress 或 Ebay + AliExpress 或三者。
我创建了一个接口:
public interface ProductsService {
List<Product> getProducts();
}
以及实现此接口的classes:
public class AmazonProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Amazon Products
}
}
public class EbayProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Ebay Products
}
}
到目前为止,我设法让它们工作,我还有一些适配器 classes 从服务获取信息并将它们调整为我定义的 POJO。
问题来了,因为我需要提供一种机制来模拟每个不同的服务。我的意思是,我需要为亚马逊、Ebay 和我的 Spring 启动应用程序需要联系的每个供应商创建一个模拟。
在另一个项目中,我使用了 Spring 配置文件,这很有用,因为我能够定义一个 "mock" 配置文件,但在那种情况下,我只有一项服务,在这种情况下,我有很多其中实现了相同的接口。
到目前为止,我尝试的是:
public class MockAmazonProductsService implements ProductsService {
public List<Product> getProducts() {
return new ArrayList<Product>();
}
}
我也创建了它的配置:
@Configuration
@Profile("mockamazon")
public class MockAmazonProductsServiceAutoconfiguration {
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
}
我为 Ebay 服务做了同样的事情(配置文件是 "mockebay")。
我的问题是,设置配置文件后如何调用模拟服务,例如:
spring.profiles.active=mockamazon
在模拟的要求之前我有以下 class:
@Service
public class ProductsServiceFactory {
@Autowired
@Qualifier("AmazonProductsService")
private ProductsService amazonProductsService;
@Autowired
@Qualifier("EbayProductsService")
private ProductsService ebayProductsService;
public List<ProductsService> getProductsService(String selectedServicesParameter) {
String[] selectedServices = selectedServicesParameter.split(",");
List<ProductsService> servicesList = new ArrayList<>();
for (String selectedService : selectedServices) {
if (selectedService.equals("AMAZON") {
servicesList.add(amazonProductsService);
} else if (selectedService.equals("EBAY") {
servicesList.add(ebayProductsService);
}
}
return servicesList;
}
}
但是现在,我不确定如何调用模拟服务。我想为模拟服务创建一个额外的服务工厂,但我可能会遇到只需要模拟一个服务而不是所有服务的场景。
如有任何建议,我们将不胜感激。
我不能说我的解决方案是完美的,但它确实有效。
您可以为每个案例创建配置文件并进行配置:
@Configuration
public class MockServiceAutoconfiguration {
@Profile({"mockAmazon", "mockAll", "mockAmazonAndEbay"})
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
@Profile({"mockAliexpress", "mockAll"})
@Bean
public ProductsService aliexpressProductsService() {
return new MockAliexpressProductsService();
}
}