Dubbo官方网址:
http://dubbo.apache.org/zh-cn/
本案例源码下载地址:
CSDN资源下载:dubbo简单入门级代码示例
百度网盘:https://pan.baidu.com/s/1cOcfzOCW9nBiSFrMJayG6w 提取码: nkqm
使用工具:
IDE:IntelliJ IDEA 2017.2 x64
注册中心:zookeeper-3.4.5
dubbo:版本为2.5.3
安装zookeeper
在本案例中,使用zookeeper作为dubbo的注册中心,所以,我们需要先安装zookeeper,zookeeper怎么安装这里不再阐述,感兴趣的朋友可以看我的另一篇文章哈:
windows安装zookeeper 单机,伪集群,集群(集群未测试)
zookeeper安装完成后,就开始打开idea进行程序编写吧。
1. 首先,我们新建一个maven项目
直接next即可。
新建完maven工程后,因为我们需要编写 provider(服务提供者)和 consumer(服务消费者)以及一个common(公共资源,用于存放消费者和提供者需要进行RPC(远程过程调用)的接口和实体,以免进行RPC的时候需要在provider和consumer中同时维护两套需要保持一致性的接口和实体类),所以,我们使用maven的分模块方式进行程序编写,这样比较方便,所以,我们先删除工程的src文件夹。
然后,我们就来创建 provider 、consumer 和 common 的 module。
创建完module后,你会发现在src/main/java中点击右键无法创建class,如下图所示:
具体的解决方法这里不再阐述,可以参考我另一篇文章,方法也比较简单:
idea中maven的Modules中java文件夹无法创建class,test文件夹中测试类没有执行按钮的解决
到这里,provider 、consumer 和 common 三个modules全部创建好了。
之后,我们先在父maven的pom.xml里进行一些公用jar包的引入:
pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>selfStudy</groupId>
<artifactId>dubboSample</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>provider</module>
<module>consumer</module>
<module>common</module>
</modules>
<!-- 声明所用的jdk版本,以免每次maven重新编译时都会重置为1.5 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<!-- 引入的所有Jar包如下 -->
<dependencies>
<!-- springMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
<!-- zookeeper的客户端 -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
</project>
同时,因为common这个Module是用来存放一些provider和consumer在进行RPC时公用的接口和实体类的,因此provider和consumer两个module需要依赖common这个module。
只需在provider和consumer的pom.xml中分别对common的引用即可:
<!-- 添加对common的引用 -->
<dependencies>
<dependency>
<groupId>selfStudy</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
至此,所有公用Jar包引入完毕且依赖关系确认完毕。
我们假设目前需求如下,有一个小朋友要去买糖,他给出一定数量的钱,然后商店给他相应的糖。
那么我们需要有一个小孩买糖的功能,一个商店卖糖的功能。
Common
首先,我们在common类中编写需要用到的糖果实体类candy,小孩买糖的功能接口ToBuyService 以及 商店卖糖的功能接口 ShopService。
结构如下:
candy实体类代码:
package bean;
/**
* 糖果
*/
public class Candy implements java.io.Serializable{
// 糖果的名称
private String name;
// 糖果的味道
private String taste;
// 糖果的颜色
private String color;
public Candy(String name, String taste, String color) {
this.name = name;
this.taste = taste;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return String.format("糖果是:%s,味道是:%s,颜色是:%s", this.name, this.taste, this.color);
}
}
ShopService代码:
package service;
import bean.Candy;
public interface ShopService {
/**
* 售卖糖果
* @param money 金额
* @return
*/
Candy sellCandy(Integer money);
}
ToBuyService代码:
package service;
import bean.Candy;
public interface ToBuyService {
/**
* 买糖果
* @param money 妈妈给的钱(给多给少看心情啊)
* @return
*/
Candy toBuyCandy(Integer money);
}
Provider
然后,我们需要编写provider的具体代码,provider作为服务提供者,自然就是商店啦,商店提供卖糖的功能实现类shopServicelImpl,作为服务提供者的启动类SellCandyApplication以及作为dubbo服务提供者的dubbo配置xml文件,商店的代码结构如下:
shopServicelImpl是ShopService的具体实现类,代码如下:
package service.impl;
import bean.Candy;
import org.springframework.stereotype.Service;
import service.ShopService;
@Service
public class ShopServiceImpl implements ShopService{
/**
* 售卖糖果
* @param money 金额
* @return
*/
@Override
public Candy sellCandy(Integer money) {
Candy candy;
switch (money) {
case 1:
candy = new Candy("大白兔", "甜的", "白色");
break;
case 5:
candy = new Candy("卫龙", "辣的", "红色");
break;
case 10:
candy = new Candy("有钱人吃砖", "火辣辣的", "疼");
break;
default:
candy = new Candy("土", "苦的", "黑色");
break;
}
return candy;
}
}
SellCandyApplication是服务提供者的启动方法,代码如下:
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* 服务提供者启动方法
*/
public class SellCandyApplication {
public static void main(String[] args) throws IOException {
// 通过类路径加载器加载spring容器
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("dubbo-provider.xml");
// 启动spring
ioc.start();
// 向控制台打印一段话,标志服务提供者开始提供服务
System.out.println("商店开门啦!");
// 将线程阻塞住,以免还没等到消费者调用,提供者就已经结束
System.in.read();
}
}
既然provider需要暴漏服务给消费者,自然少不了dubbo的配置文件,所以,在resources目录中新建了配置文件dubbo-provider.xml,具体内容如下:
dubbo-provider.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:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- Spring包扫描。base-package:要扫描的包路径 -->
<context:component-scan base-package="service.impl"></context:component-scan>
<!-- 此工程在dubbo中的项目名称。name:项目名称 -->
<dubbo:application name="provider"></dubbo:application>
<!-- dubbo的注册中心。 protocol:协议名称,address:注册中心的URL地址 -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<!-- 服务提供者在接收服务消费者请求时的处理协议和端口。name:协议名称,port:端口号 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!-- 实现了暴漏服务的接口的真实具体实现类。id:bean的唯一标识,class:具体实现类的位置 -->
<bean id="shopServiceImpl" class="service.impl.ShopServiceImpl"></bean>
<!-- 暴漏出需要提供服务的接口。interface:提供服务的接口的位置,ref:引入的具体实现bean的ID,就是上面的那个bean的ID -->
<dubbo:service interface="service.ShopService" ref="shopServiceImpl"></dubbo:service>
</beans>
至此,provider也全部写完了,慈祥的商店老奶奶已经上线,接下来就是我们的小盆友了。
Consumer
小盆友具有去买糖的功能实现类ToBuyServiceImpl,作为消费者的启动类ToBuyApplication以及自身作为dubbo服务消费者的dubbo配置xml文件。
代码结构如下:
去买糖的功能实现类ToBuyServiceImpl:
package service.impl;
import bean.Candy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import service.ShopService;
import service.ToBuyService;
@Service
public class ToBuyServiceImpl implements ToBuyService{
// 这里自动注入的就是dubbo-consumer.xml中通过dubbo:reference标签引入的shopService了
@Autowired
ShopService shopService;
/**
* 买糖
* @param money 妈妈给的钱(给多给少看心情啊)
* @return
*/
@Override
public Candy toBuyCandy(Integer money) {
// 通过dubbo:reference标签引入的shopService来调用服务提供者(也就是商店)所暴漏的远程服务(也就是卖糖)
return shopService.sellCandy(money);
}
}
作为消费者的启动类ToBuyApplication:
import bean.Candy;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.ToBuyService;
import java.util.Scanner;
public class ToBuyApplication {
public static void main(String[] args) {
// 通过类路径加载器加载spring容器
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
// 通过spring容器获取bean
ToBuyService toBuyService = ioc.getBean(ToBuyService.class);
// 用于获取控制台输入
Scanner scanner = new Scanner(System.in);
while (true) {
// 读取控制台中用户输入的金额
System.out.println("小老弟,阿姨今天给你多少钱买糖啊?");
Integer money = scanner.nextInt();
// 调用bean的方法
Candy candy = toBuyService.toBuyCandy(money);
// 将结果打印输出
System.out.println(candy);
}
}
}
以及作为dubbo消费者的dubbo配置xml文件:
dubbo-consumer.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:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- Spring包扫描。base-package:要扫描的包路径 -->
<context:component-scan base-package="service.impl"></context:component-scan>
<!-- 此工程在dubbo中的项目名称。name:项目名称 -->
<dubbo:application name="consumer"></dubbo:application>
<!-- dubbo的注册中心。 protocol:协议名称,address:注册中心的URL地址 -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<!-- 引入远程服务提供者暴漏的服务接口以便进行方法调用。interface:服务提供者暴漏的接口位置,需要与对应的dubbo-provider.xml的dubbo:service接口中的interface保持一致,id:引入的接口作为bean的id -->
<dubbo:reference interface="service.ShopService" id="shopService"></dubbo:reference>
</beans>
至此,我们的代码就写完了,来运行一下试试吧!
1. 首先启动服务提供者,运行SellCandyApplication类中的main方法:
2. 其次启动服务消费者,运行ToBuyApplication类中的main方法:
至此,我们的简单入门级dubbo+zookeeper示例就编写结束啦,感谢看到这的小伙伴,谢谢您!