5.Dubbo2.5.3泛化引用和泛化实现

转载请出自出处:http://www.cnblogs.com/hd3013779515/

1.泛化引用

泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。

(1)服务提供者

整体结构

image

模型User.java

package cn.ljh.dubbo.model;

public class User {
    private int id;
    private String username;
    private String password;
    
    get set ...

}

服务接口HelloService.java

package cn.ljh.dubbo.service;

import cn.ljh.dubbo.model.User;

public interface HelloService {
    public String sayHello(String name); 
    public User getUser(User user);
}

服务接口实现HelloServiceImpl.java

package cn.ljh.dubbo.service.impl;

import cn.ljh.dubbo.model.User;
import cn.ljh.dubbo.service.HelloService;

public class HelloServiceImpl implements HelloService{

    public String sayHello(String name) {
        return "Hello World:" + name;
    }

    public User getUser(User user) {
        user.setUsername(user.getUsername() + " Response");
        return user;
    }

}

配置文件applicationProvider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 具体的实现bean -->    
    <bean id="helloservice" class="cn.ljh.dubbo.service.impl.HelloServiceImpl" />
     <!-- 提供方应用信息,用于计算依赖关系 --> 
    <dubbo:application name="hello-provider"  />
     <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.137.130:2181?backup=192.168.137.131:2181,192.168.137.132:2181"/>
     <!-- 用dubbo协议在20880端口暴露服务 --> 
    <dubbo:protocol name="dubbo" port="20880" />
     <!-- 声明需要暴露的服务接口 --> 
    <dubbo:service interface="cn.ljh.dubbo.service.HelloService" ref="helloservice" />
   
</beans>

服务提供者启动程序HelloServiceTest.java

package cn.ljh.dubbo.service;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloServiceTest {
     public static void main(String[] args) {  
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(    
                    new String[]{"applicationProvider.xml"});    
            context.start();   
            System.out.println("服务注册成功");
            try {  
                System.in.read();//让此程序一直跑,表示一直提供服务  
            } catch (IOException e) {         
                e.printStackTrace();  
            }    
        }  
}

(2)服务消费者

整体结构

image

模型User.java 和 服务接口HelloService.java 在服务消费者中没有。

配置文件applicationConsumer.xml

在dubbo:reference中增加generic="true"

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
 
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="hello-consumer"  />
 
    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.137.130:2181?backup=192.168.137.131:2181,192.168.137.132:2181" />
 
    <!-- 生成远程服务代理,可以和本地bean一样使用HelloService -->
    <dubbo:reference id="helloService" interface="cn.ljh.dubbo.service.HelloService" generic="true"/>
    
</beans>

服务消费者启动程序HelloServiceConsumerTest.java

在程序中使用了泛化接口GenericService和参数map。

package cn.ljh.dubbo.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.dubbo.rpc.service.GenericService;

public class HelloServiceConsumerTest {
    public static void main(String[] args) {  
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(  
                new String[] { "applicationConsumer.xml" });  
          
        context.start(); 
        
        //泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示
        //用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用 
        GenericService providerService = (GenericService) context.getBean("helloService");  

        //基本类型以及Date,List,Map等不需要转换,直接调用
        Object result = providerService.$invoke(
                "sayHello", new String[] { "java.lang.String" }, new Object[] { "Tom" });
        
        System.out.println(result);
        
        // 用Map表示POJO参数,如果返回值为POJO也将自动转成Map 
        Map<String, Object> user = new HashMap<String, Object>(); 
        user.put("id", "100");
        user.put("username", "Lily"); 
        user.put("password", "yyy"); 
        //如果返回POJO将自动转成Map
        Object result2 = providerService.$invoke("getUser", new String[]{
                "cn.ljh.dubbo.model.User"}, new Object[]{user}); 
        
        Map<String, Object> user2 = (Map<String, Object>)result2;
        
        System.out.println("id:"+user2.get("id")
                + " username:"+user2.get("username")
                + " password:"+user2.get("password"));
        
        try {  
            System.in.read();//让此程序一直跑
        } catch (IOException e) {         
            e.printStackTrace();  
        }    
    }  
}

(3)测试结果

如下可以看出能够正确的调用和参数转换。

image

2.泛化实现

泛接口实现方式主要用于服务器端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的远程服务Mock框架,可通过实现GenericService接口处理所有服务请求。

(1)服务提供者

整体结构

image

模型User.java 和 服务接口HelloService.java 没有。

服务接口实现HelloServiceImpl.java

使用了GenericService接口

package cn.ljh.dubbo.service.impl;

import java.util.Map;

import com.alibaba.dubbo.rpc.service.GenericException;
import com.alibaba.dubbo.rpc.service.GenericService;

public class HelloServiceImpl implements GenericService{

    public Object $invoke(String method, String[] parameterTypes, Object[] args)
            throws GenericException {
        
        if ("sayHello".equals(method)) {
            return "Hello World:" + args[0];
        }else if ("getUser".equals(method)) {
            Map<String, Object> user = (Map<String, Object>)args[0];
            user.put("username", user.get("username") + " Response");
            return user;
        }
        
        return null;
    }
}

配置文件applicationProvider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 具体的实现bean -->    
    <bean id="helloservice" class="cn.ljh.dubbo.service.impl.HelloServiceImpl" />
     <!-- 提供方应用信息,用于计算依赖关系 --> 
    <dubbo:application name="hello-provider"  />
     <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.137.130:2181?backup=192.168.137.131:2181,192.168.137.132:2181"/>
     <!-- 用dubbo协议在20880端口暴露服务 --> 
    <dubbo:protocol name="dubbo" port="20880" />
     <!-- 声明需要暴露的服务接口 --> 
    <dubbo:service interface="cn.ljh.dubbo.service.HelloService" ref="helloservice" />
   
</beans>

服务提供者启动程序HelloServiceTest.java

package cn.ljh.dubbo.service;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloServiceTest {
     public static void main(String[] args) {  
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(    
                    new String[]{"applicationProvider.xml"});    
            context.start();   
            System.out.println("服务注册成功");
            try {  
                System.in.read();//让此程序一直跑,表示一直提供服务  
            } catch (IOException e) {         
                e.printStackTrace();  
            }    
        }  
}

(2)服务消费者

整体结构

image

模型User.java

package cn.ljh.dubbo.model;

public class User {
    private int id;
    private String username;
    private String password;
    
    get set...

}

服务接口HelloService.java

package cn.ljh.dubbo.service;

import cn.ljh.dubbo.model.User;

public interface HelloService {
    public String sayHello(String name); 
    public User getUser(User user);
}

配置文件applicationConsumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
 
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="hello-consumer"  />
 
    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.137.130:2181?backup=192.168.137.131:2181,192.168.137.132:2181" />
 
    <!-- 生成远程服务代理,可以和本地bean一样使用HelloService -->
    <dubbo:reference id="helloService" interface="cn.ljh.dubbo.service.HelloService"/>
    
</beans>

服务消费者启动程序HelloServiceConsumerTest.java

package cn.ljh.dubbo.service;

import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.ljh.dubbo.model.User;

public class HelloServiceConsumerTest {
    public static void main(String[] args) {  
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(  
                new String[] { "applicationConsumer.xml" });  
          
        context.start(); 
        
        HelloService providerService = (HelloService) context.getBean("helloService");  

        System.out.println(providerService.sayHello("Tom"));
        
        User user = new User();
        user.setId(100);
        user.setUsername("Lily test");
        user.setPassword("yyy");
        
        User user2 = providerService.getUser(user);
        
        System.out.println("id:"+user2.getId()
                + " username:"+user2.getUsername()
                + " password:"+user2.getPassword());
        
        try {  
            System.in.read();//让此程序一直跑
        } catch (IOException e) {         
            e.printStackTrace();  
        }    
    }  
}

(3)测试结果

如下可以看出能够正确的调用和参数转换。

image

参考:

http://dubbo.io/User+Guide-zh.htm

原文地址:https://www.cnblogs.com/hd3013779515/p/6903623.html