在MicroService開發中常常會遇到一個問題,本身的服務須要調用其它小組的服務,可是其餘小組的服務尚未完成。爲了避免耽誤進度,咱們就須要先實現一個Mock的服務,最後再切換到真正的外部服務上去。同時,一旦外部服務出現問題,爲了避免阻塞本地開發,咱們須要很方便的切換到Mock服務上去。經過修改配置文件裏面的內容,能夠實現不修改代碼來切換不一樣的服務。java
通用服務接口:ide
public interface OrderAtpChecker { /** * @param order order to be checked by ATP * @param tenant tenant id for client * @return a map whose key is the order line id and value is the validity of its apt check result */ Map<OrderLineId, Boolean> atpCheck(Order order, String tenant); String getType(); }
不一樣的服務實現:this
public class MockOrderAtpChecker implements OrderAtpChecker { @Override public Map<OrderLineId, Boolean> atpCheck(final Order order, final String tenant) { if (null == order) { throw new IllegalArgumentException("Can't atp check a null order."); } return order.getOrderLines().parallelStream() .collect(toMap(OrderLine::getId, o -> o.getQuantity() < 100)); } @Override public String getType() { return "Mock"; } }
public class OrderAtpChecker implements OrderAtpChecker { @Override public Map<OrderLineId, Boolean> atpCheck(final Order order, final String tenant) { ............ } @Override public String getType() { return "Inventory"; } }
Service Factory的實現:接口
@Service public class InventoryServiceFactory { @Autowired private List<OrderAtpChecker> services; private static final Map<String, OrderAtpChecker> myServiceCache = new HashMap<>(); @PostConstruct public void initMyServiceCache() { for (final OrderAtpChecker service : this.services) { myServiceCache.put(service.getType(), service); } } public static OrderAtpChecker getService(final String type) { final OrderAtpChecker service = myServiceCache.get(type); if (service == null) throw new RuntimeException("Unknown service type: " + type); return service; } }
具體調用服務的地方:
開發
@Value("${inventory_service}") private String serviceType; private OrderAtpChecker orderAtpChecker; this.orderAtpChecker = InventoryServiceFactory.getService(this.serviceType);