dubbo里面的GenericService干啥的


兩個用途一直是泛化服務,一種是泛化引用。前者是為了provider省事,后者是消費者省事。先介紹泛化服務怎么做到的:

比如提供者想省事,雖然提供了10個方法,但是不想在接口里面寫十個方法,也就不用給這十個方法做函數聲明、參數聲明了。直接通過:

ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
        service.setApplication(new ApplicationConfig("generic-provider"));
        service.setRegistry(new RegistryConfig("N/A"));
        service.setProtocol(new ProtocolConfig("dubbo", 29581));
        service.setInterface(DemoService.class.getName());
        service.setRef(new GenericService() {

            public Object $invoke(String method, String[] parameterTypes, Object[] args)
                    throws GenericException {
                if ("sayName".equals(method)) {
                    return "Generic " + args[0];
                }
                if ("throwDemoException".equals(method)) {
                    throw new GenericException(DemoException.class.getName(), "Generic");
                }
                if ("getUsers".equals(method)) {
                    return args[0];
                }
                return null;
            }
        });
        service.export();

  也就是通過method不同,直接返回不同處理結果,隱藏了方法和參數聲明。上面雖然 service.setInterface(DemoService.class.getName()),這里傳入的是接口的str名稱。也就是說通過generic,provider已經完全不依賴interface了,只是用到這個接口的名稱字符串用做servericekey用的。

 

之所以能這樣操作,消費者在調用的時候,需要在url里面指定generic=true,那么在經過filter鏈的時候,在GenericImplFilter會做generic處理

把method-name設置成$invoke

parameter-types由於提供者不一定有,於是傳入類型的string類型。

args按照pojo或者java-bean進行序列化成一個map,里面指定了參數的class類型、每個filed的value。

 

provider不會把這個map做逆序列化處理,直接原樣返回這個map,所以可以看到這個generic的provider能夠處理的東西比較有限。消費者在得到結果的時候,依然是一個map,那么在GenericImplFilter里面,把invoke得到的結果逆序列化成具體的對象。也就是說由GenericImplFilter序列化成一個map,你自己負責逆序列化。

 

 

 

對於泛化引用的話,例子如下:

 

ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
            reference.setApplication(new ApplicationConfig("generic-consumer"));
            reference.setInterface(DemoService.class);
            reference.setUrl("dubbo://127.0.0.1:29581?scope=remote");
            reference.setGeneric(true);
            GenericService genericService = reference.get();
            try {
                List<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
                Map<String, Object> user = new HashMap<String, Object>();
                user.put("class", "com.alibaba.dubbo.config.api.User");
                user.put("name", "actual.provider");
                users.add(user);
                users = (List<Map<String, Object>>) genericService.$invoke("getUsers", new String[]{List.class.getName()}, new Object[]{users});
                

  

消費者直接使用$invoke方法,不用考慮provider到底提供了哪些方法,通過字符串getuser調用,參數類型也不用關心,直接用map描述參數的類型和value。

provider在被調用的時候,還是GenericImplFilter這個filter里面,由provider通過map進行逆序列化,畢竟provider提供的方法里面是按照這個參數類型進行處理的,所以必須從map轉化成真正的類型,處理完成以后,還要逆序列化成map才能返回給consumer,因為consumer只認識map,不認識具體參數類型。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM