转载请出自出处:http://www.cnblogs.com/hd3013779515/
1.泛化引用
泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。
(1)服务提供者
整体结构
模型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)服务消费者
整体结构
模型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)测试结果
如下可以看出能够正确的调用和参数转换。
2.泛化实现
泛接口实现方式主要用于服务器端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的远程服务Mock框架,可通过实现GenericService接口处理所有服务请求。
(1)服务提供者
整体结构
模型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)服务消费者
整体结构
模型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)测试结果
如下可以看出能够正确的调用和参数转换。
参考: