內部服務路由實現的方案探討
阿新 • • 發佈:2018-12-30
問題
對於一個業務介面服務它可以有多個實現類。對於使用者來說,需要指定它所使用的是哪一個實現。比如一個介面:
介面定義
interface DemoService{ void printStr(String str); } @Service("printerService") class PrinterServiceImpl implements DemoService{ public void printStr(String str){ System.out.println("use printer print"+str); } } @Service("copyerService") class CopyerServiceImpl implements DemoService{ public void printStr(String str){ System.out.println("use copyer print"+str); } }
(比如上述的介面對應的一個業務場景發簡訊,131,132,133走聯通的通道發出去; 136,137,139走移動的通道發出去;等等業務情形)
當我們在業務類中使用這個上述介面時,需要明確的指定我們需要使用的是哪一個實現類介面;對於程式碼多數情形定義如下:
業務程式碼實現
public class BizClazz implements BizInterface{ @Autowired @Qualifier("printerService") private DemoService printerService; @Autowired @Qualifier("copyerService") private DemoService copyerService; public void bizMethod(String str,String routeCode){ if("copyer".equals(routeCode){ copyerService.printStr(Str); }else{ printerService.println(Str); } } }
如果按照這個思路,業務程式碼中處處都是這樣的if else 程式碼,那麼能否解決掉這樣的程式碼呢?答案是肯定的。對於服務實現類的路由,在java中最好的解決辦法即為代理+反射。
解決方案
重新定義介面
package c.z.route; @RouteService //介面增加註解 interface DemoService{ void printStr(String str,@RouteParam String routeCode/*路由引數增加註解*/); } @Service("printerDemoService")/*命名規則為 routeCode 小寫+介面的短名 */ class PrinterServiceImpl implements DemoService{ public void printStr(String str,String routeCode){ System.out.println("use printer print"+str); } } @Service("copyerDemoService") class CopyerServiceImpl implements DemoService{ public void printStr(String str ,String routeCode){ System.out.println("use copyer print"+str); } }
業務程式碼重構
public class BizClazz implements BizInterface{
@Autowired
@Qualifier("c.z.route.DemoService")/*介面代理實現的命名規則預設為:介面的全稱*/
private DemoService demoService;
public void bizMethod(String str,String routeCode){
demoService.printStr(str,routeCode);
}
}
適用範圍
即在定義介面時,每個方法都需要顯示的傳遞路由引數;
這樣我們的程式碼就可以簡潔便利,對於後期的擴充套件也是相當的便利。
至於具體程式碼實現以及使用方式,請參見 routeservice專案