• Stars
    star
    142
  • Rank 258,426 (Top 6 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

本项目的目标是将 Dubbo 融入到 Spring Cloud Alibaba 生态中,使微服务之间的调用同时具备 RESTful 和 Dubbo 调用的能力。做到对业务代码无侵入,无感知;引入 JAR 包则微服务间调用使用 Dubbo,去掉 JAR 包则使用默认的 RESTful;实现参考的是 Spring Cloud 中文社区的 Spring Cloud Dubbo 项目。

Spring Cloud Alibaba Dubbo

博客

目标

Spring Cloud Alibaba Dubbo 项目的目标是将 Dubbo 融入到 Spring Cloud Alibaba 生态中,使微服务之间的调用同时具备 RESTful 和 Dubbo 调用的能力。做到对业务代码无侵入,无感知;引入 JAR 包则微服务间调用使用 Dubbo,去掉 JAR 包则使用默认的 RESTful;实现参考的是 Spring Cloud 中文社区的 Spring Cloud Dubbo 项目。

Nacos

既然已经将 Dubbo 集成进了 Spring Cloud Alibaba,那么理所当然的我们的注册中心也不再采用 Zookeeper 方案而是转为 Nacos 方案了,部署 Nacos 请参考我的 服务注册与发现 章节

注:截止到博客发表时间 2019 年 03 月 13 日,Nacos 已发行版为 0.9.0,在 0.8.0 时登录 Nacos 需要使用账号密码,默认账号密码为 nacos/nacos

实现基于 Feign 的注册方案

由于 Nacos、Dubbo、Spring Cloud Alibaba 都是阿里系产品,所以我们可以很容的将 Dubbo 和 Http 服务注册到 Nacos 中。

此时服务提供者即注册了 Dubbo 又注册了 Http 服务,服务消费者根据配置方式可以在 Dubbo 与 Http 调用中随意切换

服务提供者

服务提供者在使用 Dubbo 注册服务时是需要使用 @Service 注解将服务注册到注册中心的,现在改用 @FeignClient 注解来注册

spring-cloud-alibaba-dubbo-provider-api 项目中定义的 API 接口为例

package com.funtl.alibaba.dubbo.provider.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient("provider")
public interface ProviderService {
    @GetMapping("/hi")
    String hi();
}

spring-cloud-alibaba-dubbo-provider-service 项目中实现接口为例

package com.funtl.alibaba.dubbo.provider.service.impl;

import com.funtl.alibaba.dubbo.provider.service.ProviderService;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderServiceImpl implements ProviderService {
    @Override
    public String hi() {
        return "Hi Spring Cloud Alibaba Dubbo";
    }
}

以上代码是一个典型的 Spring Cloud RESTFul API,服务提供者需要做的就是引入 Dubbo 相关依赖,扫描包含 @FeignClient 注解的类并注册到 Nacos 即可,关键代码在 spring-cloud-alibaba-dubbo-core 项目的 FeignClientToDubboProviderBeanPostProcessor 类中

    /**
     * Registers Beans whose classes was annotated {@link FeignClient}
     *
     * @param packagesToScan The base packages to scan
     * @param registry       {@link BeanDefinitionRegistry}
     */
    private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {

        DubboClassPathBeanDefinitionScanner scanner =
                new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);

        BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);

        scanner.setBeanNameGenerator(beanNameGenerator);

        scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class, true, true));

        for (String packageToScan : packagesToScan) {

            // Registers @Service Bean first
            scanner.scan(packageToScan);

            // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not.
            Set<BeanDefinitionHolder> beanDefinitionHolders =
                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);

            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {

                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                    registerServiceBean(beanDefinitionHolder, registry, scanner);
                }

                if (logger.isInfoEnabled()) {
                    logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " +
                            beanDefinitionHolders +
                            " } were scanned under package[" + packageToScan + "]");
                }

            } else {

                if (logger.isWarnEnabled()) {
                    logger.warn("No Spring Bean annotating Dubbo's @Service was found under package["
                            + packageToScan + "]");
                }

            }

        }

    }

服务消费者

服务消费者需要依赖 spring-cloud-alibaba-dubbo-provider-api,并直接使用 @Autowired 注解即可实现注入,可以不使用 Dubbo 提供的 @Reference 注解

package com.funtl.alibaba.dubbo.consumer.service;

import com.funtl.alibaba.dubbo.provider.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestService {

    @Autowired
    private ProviderService providerService;

    @GetMapping("/test")
    public String test() {
        return providerService.hi();
    }
}

以上代码是一个典型的 Spring Cloud Feign 调用。我们只需要替换 Feign 的实现。产生 ProviderService 接口的 ProxyBean 时,使用 Dubbo 产生的 Bean 替换默认的 Feign 产生的 RESTFul 调用的 Bean 即可,关键代码在 spring-cloud-alibaba-dubbo-core 项目的 DubboFeignBuilder 类中

    @Override
    public <T> T target(Target<T> target) {
        ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder
                .create(defaultReference, target.getClass().getClassLoader(), applicationContext)
                .interfaceClass(target.type());

        try {
            T object = (T) beanBuilder.build().getObject();
            return object;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

消费者使用 RESTFul 调用

只需将 Dubbo 相关依赖排除即可

<dependency>
    <groupId>com.funtl</groupId>
    <artifactId>spring-cloud-alibaba-dubbo-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.funtl</groupId>
            <artifactId>spring-cloud-alibaba-dubbo-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </exclusion>
    </exclusions>
</dependency>

More Repositories

1

spring-cloud-alibaba-my-shop

利用 Spring Cloud Alibaba 微服务架构解决方案重构《走向单体地狱》阶段开发的 MyShop 项目,以便于我们更好的理解微服务架构,将知识点运用到实践中。
Java
798
star
2

MyShopPlus

MyShopPlus 项目致力于推广并普及 微服务架构 思想,采用全新 服务网格 系统打造电商生态级产品。
Java
547
star
3

spring-cloud-netflix-itoken

iToken 项目是基于 Spring Boot + Spring Cloud 的综合练习项目,旨在帮助大家更好的理解和掌握微服务架构思想及相关知识点,为了能够让新人(尚未入行的同学们)了解企业开发中从立项到上线的大概流程,做了一个相对完整的设计,致使本人无法在有限时间内(因为要带新班)完成整个项目的研发,还请各位看官海涵。但最最重要的编程思想与编程方法已经传达到位,剩下的就是希望各位同学将所学知识内化吸收、融会贯通做出真正属于自己的产品。
Java
251
star
4

ssm-my-shop

MyShop 单体地狱版
JavaScript
191
star
5

dubbo-my-shop

该综合练习项目是将之前的《走向单体地狱》MyShop 从传统的 SSM 项目改造成基于 Spring Boot + Dubbo + Zookeeper 的微服务架构项目,旨在帮助大家更好的理解架构是演化而来的,不是设计出来的思想;当传统方式已经不能满足我们的需求时,我们就需要寻找新的解决方案了;
JavaScript
95
star
6

JavaBase

Java 基础阶段案例代码
Java
4
star