参考地址:
dubbo官网:http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.html
博客:http://www.cnblogs.com/lighten/p/6828026.html
以上两个教程经实践发现都有部分谬误,本教程做了一定更正
dubbo是一个分布式服务框架,由阿里巴巴的工程师开发,致力于提供高性能和透明化的RPC远程服务调用。可惜的是该项目在2012年之后就没有再更新了,之后由当当基于dubbo开发了dubbox。这里对dubbo的入门构建进行简单的介绍。不涉及dubbo的运行机制,只是搭建过程,方便学习者快速构建项目,运行、熟悉该框架。
dubbo提供了两种构建项目的方法:
<!--如果引入的是2.6.2以下版本,xml文件头引入的xsd地址会报错-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.3</version>
<exclusions>
<exclusion>
<!-- 排除传递spring依赖 -->
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<!--下面分别是两种不同的zookeeper客户端实现,选择一种就好-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<!--后期可能还会用到如下zookeeper客户端jar包依赖,但是目前这个demo不引入也没有问题-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
</dependency>
<!--spring配置方式,自然需要spring相关的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.17.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--打印日志相关-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
zkclient和curator
curator和zkclient分别为两种不同的zookeeper实现,两者使用的同时都需要开启先zookeeper注册中心的服务端。(关于如何下载配置并启动zookeeper服务端,参考win10环境下搭建zookeeper伪集群)
在本项目中,它默认是使用了curator实现的,要改成zkclient实现,需要在<dubbo:registry address="zookeeper://127.0.0.1:2181/" client="zkclient" />
标签中加入 client="zkclient"
,并换成zkclient的依赖。
(在dubbo官网中称2.5以上的dubbo版本默认使用zookeeper实现,但是实测结果却相反)
package dubboXml;
public interface DemoService {
String sayHello(String name);
}
实现服务接口
package dubboXml;
public class DemoServiceImpl implements DemoService{
public String sayHello(String name) {
return "Hello " + name;
}
}
spring配置
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="dubboXml.DemoService" ref="demoService" />
<!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="dubboXml.DemoServiceImpl" />
</beans>
读取配置,提供服务
package dubboXml;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
context.start();
System.in.read(); // 按任意键退出
}
}
spring配置
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app" />
<!-- 使用zookeeper注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="demoService" interface="dubboXml.DemoService" />
</beans>
读取配置,调用服务
package dubboXml;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Consumer {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
context.start();
DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
String hello = demoService.sayHello("nihao"); // 执行远程方法
System.out.println( hello ); // 显示调用结果
}
}
最终结果:
我的目录结构:
maven配置同上。
服务接口
package com.common.server;
import java.util.List;
public interface DemoService {
public String greet(String name);
public List<User> getUsers();
}
传输对象:实现序列化接口
package com.common.server;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String sex;
public User(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
实现接口(注意加上相应注解)
package com.provider;
import com.alibaba.dubbo.config.annotation.Service;
import com.common.server.DemoService;
import com.common.server.User;
import java.util.ArrayList;
import java.util.List;
/**
* 实现类上打上service注解:注意,是dubbo的service注解
*/
@Service
public class DemoServiceImpl implements DemoService {
@Override
public String greet(String name) {
return "Hello " + name;
}
@Override
public List<User> getUsers() {
List<User> list = new ArrayList<>();
User user1 = new User("张三",10,"男");
User user2 = new User("李四",11,"女");
User user3 = new User("王五",12,"男");
list.add(user1);
list.add(user2);
list.add(user3);
return list;
}
}
xml配置
(与全xml配置服务的方式相比,这里去掉了bean和<dubbo:service>
,使用<dubbo:anotition>
取代了,相当于自动扫描并暴露服务)
<?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="provider" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
<!--<dubbo:registry address="N/A"/>-->
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 注解实现,指向服务提供者实现类的包扫描-->
<dubbo:annotation package="com.provider" />
</beans>
开启服务提供
package com.provider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* 服务提供者
*/
public class Provider {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
context.start();
System.in.read();
}
}
类中注入并使用远程服务代理(为什么不在加载spring文件的类中注入?因为那是入口)
package com.consumer;
import com.alibaba.dubbo.config.annotation.Reference;
import com.common.server.DemoService;
import org.springframework.stereotype.Component;
/**
* 服务消费者:service是spring的注解
*/
@Component("anotationConsumer")
public class AnotationConsumer {
/**
* 远程服务代理,可以和本地bean一样使用demoService
*/
@Reference(check = false)
private DemoService demoService;
public void print(){
System.out.println(demoService.greet("张三"));
System.out.println(demoService.getUsers());
}
}
consumer.xml spring配置文件
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="consumer"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
<!--指向服务调用者所在的包-->
<dubbo:annotation package="com.consumer" />
<!-- 配置spring注解包扫描 -->
<context:component-scan base-package="com.consumer"></context:component-scan>
</beans>
启动服务
package com.consumer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Consumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
context.start();
AnotationConsumer anotationConsumer = (AnotationConsumer) context.getBean("anotationConsumer");
anotationConsumer.print();
}
}
调用结果:
原文:https://www.cnblogs.com/iisme/p/10622712.html