RPC呼叫及其系統單入參統一介面多路由到子系統實現,spring單介面多實現例項
阿新 • • 發佈:2018-12-26
有一種業務場景,比如接入AWS和阿里雲服務的雲監控模組,平臺單獨抽象出統一的入參物件和返回的VO物件,然後建立業務介面,阿里雲和AWS的業務介面實現同一個業務介面。但是拿到應用層去呼叫,如果每次都根據返回的入參型別都用條件判斷,作為驗證aws或者阿里雲型別的欄位,不但加大了工作量,也非常的不優雅。所以可以抽象出一個門面物件來,在門面物件中進行業務校驗,然後比較那個業務實現是因該執行的來返回還應用層。下面是具體的實現demo
1、建立業務介面類MyService,及其兩個實現類
package com.chinamsp.mytest.test; public interface MyService { Object test(); }
package com.chinamsp.mytest.test;
import org.springframework.stereotype.Service;
@Service("ALIYUN")
public class ServiceImplALIYUN implements MyService {
@Override
public Object test() {
return "aliyun";
}
}
package com.chinamsp.mytest.test; import org.springframework.stereotype.Service; @Service("AWS") public class ServiceImplAWS implements MyService { @Override public Object test() { return "AWS"; } }
當然如果有需求,也可以自定會一個標籤進行驗證,此處只講解思想,具體實現各位小夥伴何以自己實現
2、將所有實現了MyService的實現類拿到一個集合中,此處建立一個外觀類,也作為生產service的工廠類
package com.chinamsp.mytest.test; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.*; @Component public class ServiceTypeFactory implements ApplicationContextAware { private static Map<String, MyService> serviceBeanMap =new HashMap<>(32); //專案啟動時候載入上下文物件讀入MyService型別的所有實現類,然後賦值給上面生命的map @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map<String, MyService> map = applicationContext.getBeansOfType(MyService.class); for (Map.Entry<String,MyService> entry: map.entrySet()) { serviceBeanMap.put(entry.getKey(),entry.getValue()); } } //根據型別返回需要的實現類 public static <T extends MyService> T getService(String type){ return (T)serviceBeanMap.get(type); } }
3、業務層排程使用例項
package com.chinamsp.mytest.test;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
//比如type傳入AWS則拿到的service是AWS的實現類
@GetMapping("/test/{type}")
public void test(@PathVariable String type){
MyService service = ServiceTypeFactory.getService(type);
System.out.println(service.getClass().getName());
}
}
實際業務場景的如餐肯定不是單一的一個欄位,可以用@requestBody 建立一個統一的入參物件對條件進行包裝與過濾
到此就搞定了,還有要注意的就是工廠裡的獲取方法要加上校驗,此處就不寫了,大家自己去實現吧。
此處用到的設計模式是外觀模式和工廠模式搭配,感興趣的小夥伴自行搜尋,喜歡的小夥伴別忘了點個贊和關注下