本文将介绍怎样使用Dubbo的API去暴露和调用远程服务。下图是项目在IDEA中的项目结构图:

本项目总共有三个子模块,分别为 dubbo-api(定义服务的接口)、dubbo-provider(实现服务接口,然后将服务暴露出来)和 dubbo-consumer(服务消费者,消费dubbo-provider暴露出来的服务)
该子模块依赖 dubbo-api 子模块,实现了 dubbo-api 中定义的服务接口。项目结构如下图:

HelloServiceImpl.java
package com.huangx.dubbo.provider;
import com.alibaba.dubbo.config.annotation.Service;
import com.huangx.dubbo.hello.HelloService;
import com.alibaba.dubbo.rpc.RpcContext;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 服务实现
*/
@Service(version = "1.0.0")
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("[" + sdf.format(new Date()) + "] Hello " + name
+ ", request from consumer: "
+ RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response from provider: "
+ RpcContext.getContext().getLocalAddress();
}
}上面代码简单的实现了 dubbo-api 定义的服务。
Provider.java
package com.huangx.dubbo.provider;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.huangx.dubbo.hello.HelloService;
/**
* 加载 Spring 的配置文件,启动 Dubbo 服务提供者
*/
public class Provider {
public static void main(String[] args) throws Exception {
// 服务实现
HelloService helloService = new HelloServiceImpl();
// 当前应用配置
ApplicationConfig application = new ApplicationConfig();
application.setName("demo-provider");
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setProtocol("zookeeper");
registry.setAddress("127.0.0.1:2181");
// 服务提供者协议配置
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName("dubbo");
protocol.setPort(12345);
protocol.setThreads(20);
// 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口
// 服务提供者暴露服务配置
// 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
ServiceConfig<HelloService> service = new ServiceConfig<HelloService>();
service.setApplication(application);
service.setRegistry(registry); // 多个注册中心可以用setRegistries()
service.setProtocol(protocol); // 多个协议可以用setProtocols()
service.setInterface(HelloService.class);
service.setRef(helloService);
service.setVersion("1.0.0");
// 暴露及注册服务
service.export();
// 按任意键退出
System.in.read();
}
}上面代码分为:
创建 ApplicationConfig 应用配置
创建 RegistryConfig 注册配置
创建 ProtocolConfig 服务协议
创建 ServiceConfig 服务配置(一个服务需要包含 ApplicationConfig、RegistryConfig 和 ProtocolConfig )
该子模块也依赖 dubbo-api 模块,根据服务接口调用远程实现(dubbo-provider暴露的服务)。项目结构如下图:

Consumer.java
package com.huangx.dubbo.consumer;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.huangx.dubbo.hello.HelloService;
/**
* 加载 Spring 配置,启动 Dubbo 服务消费者
*/
public class Consumer {
public static void main(String[] args) {
// 当前应用配置
ApplicationConfig application = new ApplicationConfig();
application.setName("demo-consumer");
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setProtocol("zookeeper");
registry.setAddress("127.0.0.1:2181");
// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接引用远程服务
// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
ReferenceConfig<HelloService> reference = new ReferenceConfig<HelloService>();
reference.setApplication(application);
reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
reference.setInterface(HelloService.class);
reference.setVersion("1.0.0");
// 和本地bean一样使用xxxService
// 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
HelloService helloService = reference.get();
while(true) {
String result = helloService.sayHello("hello");
System.out.println(result);
}
}
}