1. 程式人生 > >RPC呼叫及其系統單入參統一介面多路由到子系統實現,spring單介面多實現例項

RPC呼叫及其系統單入參統一介面多路由到子系統實現,spring單介面多實現例項

有一種業務場景,比如接入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 建立一個統一的入參物件對條件進行包裝與過濾

到此就搞定了,還有要注意的就是工廠裡的獲取方法要加上校驗,此處就不寫了,大家自己去實現吧。

此處用到的設計模式是外觀模式和工廠模式搭配,感興趣的小夥伴自行搜尋,喜歡的小夥伴別忘了點個贊和關注下