在上一章节《Dubbo(三) 消费者、提供者工程搭建并实现远程调用》中我们简单介绍了Dubbo的概念以及使用xml方式实现了一个消费者和提供者工程,本章介绍使用注解方式实现消费者调用服务提供者Demo。

同样本章还是创建三个工程,分别为公共接口类工程、提供者工程、消费者工程。文章中包含项目全部代码。

一、公共接口类工程 service-interface:

公共接口类模块主要是为了减少提供方和消费者工程中重复的接口类代码编写,所以抽取出单独的模块,并在其他两个工程中pom中引入。

springcloud 集成 dubbo 实现远程调用_dubbo

1,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>com.xiaohui.serviceinterface</groupId>
    <artifactId>service-interface</artifactId>
    <version>1.0</version>

    <properties>
        <lombok.version>1.18.10</lombok.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>

</project>

2,UserAddress.java 、OrderService.java、UserService.java

package com.xiaohui.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress implements Serializable {

    private Integer id;
    private String userAddress;
    private String userId;
}
package com.xiaohui.service;

import com.xiaohui.domain.UserAddress;
import java.util.List;

public interface OrderService {
    public List<UserAddress> initOrder(String userId);
}
package com.xiaohui.service;

import com.xiaohui.domain.UserAddress;

import java.util.List;

public interface UserService {

    /**
     * 查询某个用户的全部地址
     * @param userId
     * @return
     */
    public List<UserAddress> queryAllUserAddress(String userId);
}

二、服务提供者工程user-service-provider

1,pom.xml 

主要包含了公共接口类模块依赖,dubbo依赖,zookeeper依赖以及zk的辅助包和dubbo需要的底层包,dubbo 内部引入了Spring包所以不用在引入Spring包。

<?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>com.xiaohui.userserviceprovider</groupId>
    <artifactId>user-service-provider</artifactId>
    <version>1.0</version>

    <dependencies>
        <!-- 公共接口类依赖 -->
        <dependency>
            <groupId>com.xiaohui.serviceinterface</groupId>
            <artifactId>service-interface</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- dubbo 依赖  内部引入了Spring包所以不用导入spring 包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.7</version>
        </dependency>
        <!-- zookeeper客户端 用于dubbo的服务注册 -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
        </dependency>
        <!-- zk辅助包 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.1.0</version>
        </dependency>
        <!-- dubbo底层封装依赖包 -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>

    </dependencies>

</project>

2,远程接口实现类UserServiceImpl.java(重点)

该类类上需要使用dubbo的@Servcice 注解进行接口暴露,并且该注解也有Spring中的@Service 注解功能,提供spring 扫描发现。 

package com.xiaohui.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.UserService;

import java.util.ArrayList;
import java.util.List;

@Service //alibaba包下的Service,包含了spring @Service功能以及暴露服务功能
public class UserServiceImpl implements UserService {

    public static List<UserAddress> address = new ArrayList<UserAddress>();
    static{
        address.add(new UserAddress(1,"西安市未央区阿房一路","10001"));
        address.add(new UserAddress(2,"郑州市中原区冬青街","10002"));
    }
    public List<UserAddress> queryAllUserAddress(String userId) {
        System.out.println("入参:"+userId);
        return address;
    }
}

3,spring 配置文件 applicationContext2.xml(重点)

在提供者工程spring配置文件中需要配置 dubbo 应用名称、dubbo注册中心地址、dubbo协议名称以及端口、dubbo的注解扫描路径。

与基于xml方式的配置对比,使用注解时在改配置文件中加入了dubbo的注解扫描路径配置<dubbo:annotation />,减少了之前的 <dubbo:service /> 和 接口实现类<bean />的配置。

<?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://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://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://dubbo.apache.org/schema/dubbo
               http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="user-service-provider"  />

    <!-- 使用zookeeper广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.0.126:2181" />
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- dubbo 包扫描路径 用于扫描使用dubbo的@Service注解类 -->
    <dubbo:annotation package="com.xiaohui.service.impl"></dubbo:annotation>
</beans>

4,服务提供者工程启动类

package com.xiaohui.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class TestProvider {

    public static void main(String[] args) throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext2.xml");
        System.out.println("provider 服务启动成功");
        System.in.read();
    }
}

三、服务消费者工程order-service-consumer 

springcloud 集成 dubbo 实现远程调用_dubbo_02

1,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>com.xiaohui.orderserviceconsumer</groupId>
    <artifactId>order-service-consumer</artifactId>
    <version>1.0</version>

    <dependencies>
        <dependency>
            <groupId>com.xiaohui.serviceinterface</groupId>
            <artifactId>service-interface</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.7</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
    </dependencies>

</project>

2,消费者接口实现类(重点)

在消费方接口实现类中 我们需要给类添加spring的@Service 注解,用于Spring 包扫描发现。在内部属性上面我们使用dubbo的@Reference注解。Reference使用在消费端,用于给消费者工程实现类属性注入注册中心接口。

package com.xiaohui.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.OrderService;
import com.xiaohui.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    @Reference
    private UserService userService;

    public List<UserAddress> initOrder(String userId) {
        return userService.queryAllUserAddress(userId);
    }
}

3,消费者工程 spring配置文件 applicationContext2.xml(重点)

在该配置文件中需要配置 dubbo应用名称、dubbo注册中心地址、spring 包扫描路径、dubbo注解扫描路径。

<?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://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://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://dubbo.apache.org/schema/dubbo
               http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="order-service-consumer"  />

    <!-- 使用zookeeper广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.0.126:2181" />

    <!-- 用于扫描消费者实现类上的@Service 加入到Spring容器中 -->
    <context:component-scan base-package="com.xiaohui.service.impl"></context:component-scan>

    <!-- 用于扫描dubbo的 @Reference 注解 进行订阅接口 -->
    <dubbo:annotation package="com.xiaohui.service.impl"></dubbo:annotation>
</beans>

4,消费方测试启动类

package com.xiaohui.test;

import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.OrderService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.util.List;

public class TestConsumer {

    public static void main(String[] args) throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext2.xml");
        OrderService orderService = context.getBean(OrderService.class);
        List<UserAddress> list = orderService.initOrder("zhang san");
        for (UserAddress address : list) {
            System.out.println(address.getUserId()+"---"+address.getUserAddress());
        }
        System.in.read();
    }
}

四、启动服务测试

启动服务提供者工程,后在启动服务消费者工程控制台分别打印如下:

springcloud 集成 dubbo 实现远程调用_zookeeper_03

springcloud 集成 dubbo 实现远程调用_spring_04

从dubbo-admin控制台可以看到生产者和消费者应用都已出现。

springcloud 集成 dubbo 实现远程调用_zookeeper_05