dubbo学习之源码创建属于自己的dubbo-demo
目录
绪论
上篇博文<一路踩坑构建Dubbo源码>谈论了如何本地构建dubbo源码,最近溪源也在努力的学习dubbo相关知识和机制,学习过程也可以称之苦不堪言吧。dubbo官网是入门学习资源重要之一;故溪源先分享中文官网:dubbo中文手册。
上网文章中也清晰地带着大家成功运行dubbo-demo
;对于像溪源这样的新手接触dubbo,学习源码估计都很难找到入手的方法,溪源也是走了不少冤枉路,所以特此写了一篇入手dubbo源码的文章,希望能够帮助伙伴们降低时间浪费,少走弯路。溪源这篇带着大家在dubbo-demo中创建自己的跟踪源码的单测用例。对于官网给与的demo用例,大家可以大胆的修改,溪源就是把demo改的面目全非。
环境搭建
借助官网的快速启动手册,以及源码包路径;
分别在dubbo-demo-interface
module中建立实体类和接口:
dubbo-demo-interface
目录结构如图:
- 定义实体User
public class User implements Serializable {
private String userId;
private String userName;
private String userLevel;
private String userAddress;
//省略get/set方法
}
注意:实体类对象要实现Serializable接口,涉及后面远程调用传输;
- 定义UserService接口
public interface UserService {
List<User> getUserAddressList();
}
- 定义OrderService
public interface OrderService {
void getUserAddressList();
}
dubbo-demo-xml
在dubbo-demo-xml
模块中分别处理服务提供者逻辑、服务消费者逻辑;
dubbo-demo-xml-provider
首先贴出代码目录结构:
这个模块下东西比较多,目前只要是溪源学习SPI,Adaptive相关知识用到,大家可以暂时忽略,可以参考溪源分享的代码和目录结构创建,或者根据大家的实际情况建立,溪源仅仅提供一种入门的方式。
- dubbo-provider.xml
具体配置如下: 注册中心zookeeper地址换成自己本地IP或者阿里云服务器公网IP。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application metadata-type="remote" name="user-provider"/>
<!-- <dubbo:metadata-report address="zookeeper://****:2181"/>-->
<!--定义包扫描路径-->
<context:component-scan base-package="org.apache.dubbo.demo.provider"/>
<dubbo:registry address="zookeeper://*****:2181" timeout="10000"/>
<dubbo:protocol name="dubbo"/>
<!--暴露服务接口,ref:指接口真正的实现类bean,实现类后面会分享-->
<dubbo:service interface="org.apache.dubbo.demo.UserService" ref="memberServiceImpl"/>
</beans>
注意:此处与官网提供的xml配置存在区别,溪源这里引入包路径扫描
机制,否则接口实现类无法使用注解@Service
等注入spring容器中,或者大家可以按照官网使用<bean>
标签注入实现类对象,如下:
<bean id="memberServiceImpl" class="org.apache.dubbo.demo.provider.impl.MemberServiceImpl"/>
- memberServiceImpl
@Service
public class MemberServiceImpl implements UserService, Serializable {
@Override
public List<User> getUserAddressList() {
List<User> userList = new LinkedList<>();
for (int i = 0; i < 2; i++) {
User user = new User();
user.setUserLevel("member");
user.setUserAddress("杭州拱墅 " + i);
userList.add(user);
}
return userList;
}
}
溪源目的是通过实例学习dubbo相关机制和实现,所以此处直接代码创建user对象,实际应用业务场景再仔细考虑;
- 主启动类
为了能够区分业务功能启动类,溪源直接将官网提供的类名改成ProviderApplication。
public class ProviderApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
context.start();
System.in.read();
}
}
服务提供者相关业务结束,下面开始实现服务消费者。
dubbo-demo-xml-consumer
代码目录如下:
consumer模块的目录结构就比较简单明了。
- dubbo-consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="org.apache.dubbo.demo.consumer"/>
<dubbo:application name="order-consumer"/>
<dubbo:registry address="zookeeper://****:2181" timeout="80000"/>
<!--引用暴露的接口-->
<dubbo:reference id="userService" check="false" interface="org.apache.dubbo.demo.UserService"/>
</beans>
- OrderServiceImpl
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private UserService userService;
@Override
public void getUserAddressList() {
List<User> userAddressList = userService.getUserAddressList();
for (User user : userAddressList) {
System.out.println(user.getUserAddress());
}
}
}
获取用户地址,并打印出来。
- 主启动类
同理,溪源将原启动类重命名为ConsumerApplication。
public class ConsumerApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
OrderService orderService = context.getBean(OrderService.class);
orderService.getUserAddressList();
System.in.read();
}
}
运行
运行程序之前,溪源再着重强调几点,也是溪源学习过程中遇到的异常或者错误问题,避免大家踩坑,再说一下:
1.实体类,服务接口实现类实现Serializable接口;
2.确保自己zookeeper注册中心正常启动;
3.检查自己是否开启包扫描机制或者是否使用xml配置文件注入bean方式;
4.溪源并没有设置启动检查选项,所以默认值为true,如果服务提供类未启动,则服务消费者先启动,会报错;
大家运行之前,再仔细核查一遍,然后先启动ProviderApplication,再启动ConsumerApplication。 运行结果如图:
溪源写的demo源码传送门。 虽然公司项目业务暂时用不dubbo,但是不代表我们就停滞不前,程序员最重要的是技能。大家如果存在好的学习资源可以私信或者评论区留言能够分享给溪源一下哈~~。溪源也是第一次接触dubbo的相关机制,如果中间存在错误之处,希望大家能够及时指正,便于改正。最后,希望能够得到大家的肯定和支持。
- PhalGo-Respones
- 数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 改写
- Otter-入门篇2(Manager安装配置)
- Java的字符串常量相关的一个问题
- [喵咪Liunx(3)]端口转发工具rinetd
- 基于PhalApi的Smarty拓展
- PhalGo-参数验证过滤
- [喵咪Redis]Redis配置文件和主从设置
- [喵咪Redis]Redis-Sentinel
- [喵咪Redis]Redis安装与介绍
- [喵咪Liunx(4)Monit进程监控
- 【第四期】GC专题
- ML中相似性度量和距离的计算&Python实现
- ASP.NET MVC Model元数据及其定制: Model元数据的定制
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python实现决策树
- NLP简报(Issue#10)
- Transformer温故知新
- 【作者解读】ERNIE-GEN : 原来你是这样的生成预训练框架!
- Python中那些低调有趣的模块
- 01背包问题讲解(动态规划)
- python实现随机森林
- 在mysql中order by是怎样工作的?
- 多线程应用 - 阻塞队列ArrayBlockingQueue详解
- Java虚拟机 - 超级详细的类加载说明
- ReentrantLock
- 多线程应用 - 阻塞队列LinkedBlockingDeque详解
- AtomicInteger详解
- 多线程应用 - 阻塞队列LinkedBlockingQueue详解
- 多线程应用 - 超详细的AQS详情