欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Gradle-SpringCloud聚合项目配置

程序员文章站 2024-02-03 21:01:22
...

版本信息

  • idea2020
  • jdk-1.8
  • gradle-6.7.1

gradle

gradle 和 maven的简单对比

详情见:Gradle vs Maven Comparison

Gradle-SpringCloud聚合项目配置

单一gradle项目的基本结构

├── gradle ------------------------------------1
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew -----------------------------------2
├── gradlew.bat -------------------------------2
├── settings.gradle ---------------------------3
└── app
    ├── build.gradle --------------------------4
    └── src
        ├── main
        │   └── java --------------------------5
        │       └── demo
        │           └── App.java
        └── test
            └── java --------------------------6
                └── demo
                    └── AppTest.java
  1. Gradle Wrapper执行后生成的文件夹
  2. Gradle Wrapper的启动脚本
  3. 用于定义生成名称和子项目的设置文件
  4. 项目程序的构建脚本
  5. 默认的Java资源文件夹
  6. 默认的Java Test文件夹

Gradle可以在没有安装Gradle的情况下使用,这时候就需要Gradle Wrapper了。Gradle Wrapper其实就是一个脚本文件,它会在没有安装Gradle的情况下为我们下载Gradle,之后我们就可以使用gradlew命令,像使用gradle一样来使用Gradle了。但是对于我们天朝用户来说,不管是Gradle还是Gradle Wrapper,都需要网络代理才能以较高的速度下载。(参考:Gradle学习笔记 使用Gradle Wrapper)

这也是为什么,在idea中,创建一个gradle项目就会有一个下载阶段~只要下载过一次就不会下载了。

多模块gradle项目的基本结构

├── gradle 
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew 
├── gradlew.bat 
├── settings.gradle 
├── buildSrc
│   ├── build.gradle 
│   └── src
│       └── main
│           └── groovy 
│               ├── demo.java-application-conventions.gradle
│               ├── demo.java-common-conventions.gradle
│               └── demo.java-library-conventions.gradle
├── app
│   ├── build.gradle 
│   └── src
│       ├── main 
│       │   └── java
│       │       └── demo
│       │           └── app
│       │               ├── App.java
│       │               └── MessageUtils.java
│       └── test 
│           └── java
│               └── demo
│                   └── app
│                       └── MessageUtilsTest.java
├── list
│   ├── build.gradle 
│   └── src
│       ├── main 
│       │   └── java
│       │       └── demo
│       │           └── list
│       │               └── LinkedList.java
│       └── test 
│           └── java
│               └── demo
│                   └── list
│                       └── LinkedListTest.java
└── utilities
    ├── build.gradle 
    └── src
        └── main 
            └── java
                └── demo
                    └── utilities
                        ├── JoinUtils.java
                        ├── SplitUtils.java
                        └── StringUtils.java

sample文件可以见gradle官网BuildJavaSample

聚合项目创建依赖

SpringBoot可以参考Spring Boot Gradle Plugin Reference Guide

别人的中文翻译:Spring Boot - Gradle Plugin

SpringCloud可以参考Spring Cloud Netflix

利用tree命令(cmd和linux都有,tree /F可以显示所有文件信息)可以生成如下的结构树,创建了一个父类工程gradle-spring-cloud-parent,里面有四个子模块:

  • gradle-spring-cloud-common
  • gradle-spring-cloud-consumer
  • gradle-spring-cloud-provider
  • gradle-spring-cloud-eureka
E:.
│  .gitignore
│  build.gradle
│  gradlew
│  gradlew.bat
│  HELP.md
│  settings.gradle
│
├─.idea
│  │  .gitignore
│  │  compiler.xml
│  │  gradle.xml
│  │  jarRepositories.xml
│  │  misc.xml
│  │  uiDesigner.xml
│  │  workspace.xml
│  │
│  └─modules
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
├─gradle-spring-cloud-common
│  │  build.gradle
│  │
│  └─src
│      ├─main
│      │  ├─java
│      │  │  └─com
│      │  │      └─yuanbaoqiang
│      │  │          └─spring
│      │  │              └─cloud
│      │  │                  └─entity
│      │  │                          Employee.java
│      │  │
│      │  └─resources
│      └─test
│          ├─java
│          └─resources
├─gradle-spring-cloud-consumer
│  │  build.gradle
│  │
│  └─src
│      ├─main
│      │  ├─java
│      │  │  └─com
│      │  │      └─yuanbaoqiang
│      │  │          └─spring
│      │  │              └─cloud
│      │  │                  │  ConsumerMainType.java
│      │  │                  │
│      │  │                  ├─config
│      │  │                  │      AtYuanbaoqiangSpringCloudConfig.java
│      │  │                  │
│      │  │                  └─handler
│      │  │                          HumanResourceHandler.java
│      │  │
│      │  └─resources
│      │          application.yml
│      │
│      └─test
│          ├─java
│          └─resources
├─gradle-spring-cloud-eureka
│  │  build.gradle
│  │
│  └─src
│      ├─main
│      │  ├─java
│      │  │  └─com
│      │  │      └─yuanbaoqiang
│      │  │          └─spring
│      │  │              └─cloud
│      │  │                      EurekaServerMainType.java
│      │  │
│      │  └─resources
│      │          application.yml
│      │
│      └─test
│          ├─java
│          └─resources
└─gradle-spring-cloud-provider
    │  build.gradle
    │
    └─src
        ├─main
        │  ├─java
        │  │  └─com
        │  │      └─yuanbaoqiang
        │  │          └─spring
        │  │              └─cloud
        │  │                  │  ProviderMainType.java
        │  │                  │
        │  │                  └─handler
        │  │                          EmployeeHandler.java
        │  │
        │  └─resources
        │          application.yml
        │
        └─test
            ├─java
            └─resources

Gradle-SpringCloud聚合项目配置

Gradle-SpringCloud聚合项目配置

打包的测试(相关设置细节在后续章节)

可以单独在不同的子模块中进行一个小小的打包测试(如果执行的是父类工程中的Task命令,则对当前整个项目都有效!):

对于consumer,我开启了jar,没有禁用bootjar,也就是说可以同时打出jar包和bootjar包:

Gradle-SpringCloud聚合项目配置

在子模块下的build文件夹中的libs文件夹中找到打出的jar包和bootJar包:

Gradle-SpringCloud聚合项目配置

在cmd终端执行java -jar consumer-0.0.1-SNAPSHOT.jar,出现报错:

C:\Users\YuanbaoQiang\Desktop>java -jar consumer-0.0.1-SNAPSHOT.jar
consumer-0.0.1-SNAPSHOT.jar中没有主清单属性

也就是说此时的jar包是不可以执行的!

在cmd终端执行java -jar consumer-0.0.1-SNAPSHOT-boot.jar

C:\Users\YuanbaoQiang\Desktop>java -jar consumer-0.0.1-SNAPSHOT-boot.jar
2020-12-04 15:08:33.076  INFO 8424 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$fc09ca35] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2020-12-04 15:08:34.005  INFO 8424 --- [           main] c.y.spring.cloud.ConsumerMainType        : No active profile set, falling back to default profiles: default
2020-12-04 15:08:35.225  INFO 8424 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=ec4303e4-0d78-3797-a1e7-256ce60d4503
2020-12-04 15:08:35.477  INFO 8424 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$fc09ca35] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-04 15:08:36.481  INFO 8424 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 4000 (http)
2020-12-04 15:08:36.547  INFO 8424 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-12-04 15:08:36.548  INFO 8424 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.21]
2020-12-04 15:08:36.575  INFO 8424 --- [           main] o.a.catalina.core.AprLifecycleListener   : Loaded APR based Apache Tomcat Native library [1.2.25] using APR version [1.7.0].
2020-12-04 15:08:36.577  INFO 8424 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
2020-12-04 15:08:36.586  INFO 8424 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2020-12-04 15:08:36.593  INFO 8424 --- [           main] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1g  21 Apr 2020]
2020-12-04 15:08:36.789  INFO 8424 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-12-04 15:08:36.790  INFO 8424 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2763 ms
2020-12-04 15:08:36.997  WARN 8424 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2020-12-04 15:08:36.998  INFO 8424 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2020-12-04 15:08:37.144  WARN 8424 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2020-12-04 15:08:37.145  INFO 8424 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2020-12-04 15:08:37.496  INFO 8424 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-04 15:08:39.546  INFO 8424 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2020-12-04 15:08:39.644  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2020-12-04 15:08:40.844  INFO 8424 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON encoding codec LegacyJacksonJson
2020-12-04 15:08:40.845  INFO 8424 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON decoding codec LegacyJacksonJson
2020-12-04 15:08:41.126  INFO 8424 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML encoding codec XStreamXml
2020-12-04 15:08:41.127  INFO 8424 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML decoding codec XStreamXml
2020-12-04 15:08:41.560  INFO 8424 --- [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2020-12-04 15:08:41.987  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2020-12-04 15:08:41.988  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2020-12-04 15:08:41.993  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2020-12-04 15:08:41.993  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2020-12-04 15:08:41.994  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2020-12-04 15:08:41.995  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2020-12-04 15:08:41.996  INFO 8424 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server

初步测试结果:jar包无法被java -jar命令执行,bootJar可以执行!

gradle-spring-cloud-parent

依赖部分

// 在这里声明plugin
plugins {
    // 引入 api 传递依赖的方法 用来代替compile
    id 'java-library'
    // Spring Boot’s dependency management can be used in a project without applying Spring Boot’s plugin to that project.
    // First, configure the project to depend on the Spring Boot plugin but do not apply it:
    id 'org.springframework.boot' version '2.1.6.RELEASE' apply false
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}

ext { // 自定义扩展 字段 这里定义版本信息
    //定义一个变量,统一规定springboot的版本
    springCloudVersion = 'Greenwich.SR2'

    // To customize a managed version you set its corresponding property.
    // For example, to customize the version of SLF4J which is controlled by the slf4j.version property:
    // ext['slf4j.version'] = '1.7.20'
    // 可以自己修改jar包的版本,但是不建议,都交给Spring管理即可,自己设定版本可能会出错
}

repositories {
    // 配置资源地址
    maven { url 'file:///E:/tools/repository'} // 这是我的maven仓库地址
    jcenter()
    mavenCentral()
}

// 子项目的通用配置
subprojects {
    // 在这里使用plugin
    /* 使用二进制插件 */
    apply plugin: 'java' /* java是Gradle的核心插件,是内置的,内置插件不需要配置依赖路,径 */
    apply plugin: 'idea' /* 同上  让Gradle自动生成Intellij的项目文件*/
    /* 注意gradle插件不再自动应用,所以这里需要指定 */
    apply plugin: 'org.springframework.boot'
    /* 依赖管理插件仍然是一个spring-boot-gradle-plugin传递依赖,所以无需在build.gradle配置中明确列出此依赖。 */
    apply plugin: 'io.spring.dependency-management' /* 依赖管理,用来传递spring的依赖 */

    // 可以使用api编译
    apply plugin: 'java-library'

    // A project can be configured to build both an executable archive and a normal archive at the same time by enabling the jar or war task:
    // 可以参考:https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/

    // 默认bootJar和bootWar is true
    // jar和war 是false
    // springboot打出的bootJar包  一般是 不能被依赖的
    // 可以参考:https://www.cnblogs.com/karlMa/p/11304524.html
    // 打出来的jar包可以子模块间相互依赖,但经过个人测试后发现不可以被执行
    // 如果不开启的话,后续是会出现模块间找不到依赖的问题!
    jar.enabled = true

    group = 'com.example'
    version = '0.0.1-SNAPSHOT' /* 项目版本 */
    /* 指定jdk版本 */
    sourceCompatibility = '1.8'
    /* java编译的时候缺省状态下会因为中文字符而失败 */
    [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'

    repositories {
        maven { url 'file:///E:/tools/repository'}
        jcenter()
        mavenCentral()
    }

    // 此时只是一个依赖管理,并不会导入任何的jar包
    // 子项目需要的时候才会真正导入
    dependencyManagement {
        imports {
            //spring bom helps us to declare dependencies without specifying version numbers.
            ///**
            //	 * The coordinates {@code (group:name:version)} of the
            //	 * {@code spring-boot-dependencies} bom.
            //	 */
            //	public static final String BOM_COORDINATES = "org.springframework.boot:spring-boot-dependencies:"
            //			+ SPRING_BOOT_VERSION;
            mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
}

By default, when the bootJar or bootWar tasks are configured, the jar or war tasks are disabled. A project can be configured to build both an executable archive and a normal archive at the same time by enabling the jar or war task:

默认的,当bootJar或者bootWar任务配置了,jar或者war任务会被禁用掉。但是可以同时构建一个可执行和普通的文件通过设置jar或者war任务可用:

jar {
	enabled = true
}

To avoid the executable archive and the normal archive from being written to the same location, one or the other should be configured to use a different location. One way to do so is by configuring a classifier:

为了避免可执行文件和普通文件生成在同一个目录,其中一个应该使用不同的位置。一种方法就是配置一个classifier:

高版本的gradle换成了archiveClassifier

bootJar {
	classifier = 'boot'
}

bootJar可以执行,但是无法在聚合项目中被其他的项目所依赖。考虑到模块间的相互依赖,每个模块需要以jar包进行打包,但是默认环境中jar或者war是disable的,需要人为的手动开启。这也是为什么需要在父类的build.gradle中的subprojects指明jar.enabled=true,这是让所有的项目都可以打成jar包,方便依赖。

gradle-spring-cloud-common

依赖部分

// jar包后的名字
archivesBaseName = 'common'
// 因为它没有主程序入口,也不需要它达成springboot的jar包
bootJar.enabled = false

打出的jar包名字:common-0.0.1-SNAPSHOT.jar(archivesBaseName + 版本信息 + .jar)

此时我执行gradle-spring-cloud-common下的bootJar是打不出jar包的(在idea结构树中的build文件夹中不存在libs文件夹)

Gradle-SpringCloud聚合项目配置

Gradle-SpringCloud聚合项目配置

并且在输出窗口中也可以看到bootJar SKIPPED这个日志信息,说明bootJar禁用成功。

Task :gradle-spring-cloud-common:compileJava
Task :gradle-spring-cloud-common:processResources NO-SOURCE
Task :gradle-spring-cloud-common:classes
Task :gradle-spring-cloud-common:bootJar SKIPPED

实体类

com.yuanbaoqiang.spring.cloud.entity.Employee

此处使用lombok可能会有后续的问题,可以自行尝试~

package com.yuanbaoqiang.spring.cloud.entity;


/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 14:03
 */
public class Employee {
    private Integer empId;
    private String empName;
    private Double empSalary;

    public Employee() {
    }

    public Employee(Integer empId, String empName, Double empSalary) {
        this.empId = empId;
        this.empName = empName;
        this.empSalary = empSalary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "empId=" + empId +
                ", empName='" + empName + '\'' +
                ", empSalary=" + empSalary +
                '}';
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Double getEmpSalary() {
        return empSalary;
    }

    public void setEmpSalary(Double empSalary) {
        this.empSalary = empSalary;
    }
}

gradle-spring-cloud-consumer

依赖部分

archivesBaseName = 'consumer'
// 为了避免可执行文件和普通文件生成在同一个目录,
// 其中一个应该使用不同的位置。一种方法就是配置一个classifier:
// 注意 classifier这种标记在gradle6.7.1的时候已经被取消了
// 换成了archiveClassifier
/*
    @Nullable
    @Deprecated
    @ReplacedBy("archiveClassifier")
    public String getClassifier() {
        ((DeprecateProperty)DeprecationLogger.deprecateProperty(AbstractArchiveTask.class, "classifier").replaceWith("archiveClassifier")).willBeRemovedInGradle7().withDslReference().nagUser();
        return (String)this.archiveClassifier.getOrNull();
    }

    @Deprecated
    public void setClassifier(@Nullable String classifier) {
        this.archiveClassifier.convention(classifier);
        this.archiveClassifier.set(classifier);
    }
    *
    */
bootJar {
    archiveClassifier = 'boot'
}


dependencies {
    // 子模块间的依赖
    implementation project(':gradle-spring-cloud-common') /* 子模块之间的依赖 */
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // eureka注册 及 ribbon负载平衡
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}

主启动类

com.yuanbaoqiang.spring.cloud.ConsumerMainType

package com.yuanbaoqiang.spring.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 14:14
 */
// 下面两个注解功能大致相同,较低版本必须使用
//@EnableDiscoveryClient  启用发现服务功能,不局限于Eureka注册中心
//@EnableEurekaClient     启用Eureka客户端功能
@SpringBootApplication
public class ConsumerMainType {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerMainType.class, args);
    }
}

配置类

com.yuanbaoqiang.spring.cloud.config.AtYuanbaoqiangSpringCloudConfig

package com.yuanbaoqiang.spring.cloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 15:03
 */
@Configuration
public class AtYuanbaoqiangSpringCloudConfig {

    @Bean
    // 这个注解让ResTemplate具有负载均衡的功能,通过调用Ribbon可以访问provider的集群
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

Handler方法

com.yuanbaoqiang.spring.cloud.handler.HumanResourceHandler

package com.yuanbaoqiang.spring.cloud.handler;

import com.yuanbaoqiang.spring.cloud.entity.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 15:05
 */
@RestController
public class HumanResourceHandler {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/ribbon/get/employee")
    public Employee getEmployeeRemote() {
        // 远程调用方法的主机地址
        // 1. 声明远程微服务的主机地址及端口号
        // String host = "http://localhost:1000";

        // 将当前远程微服务调用地址从ip地址加端口号改成“微服务名称”
        String host = "http://atyuanbaoqiang-provider";

        // 远程调用方法的具体URL 地址
        // 2. 声明具体要调用的功能的URL地址
        String url = "/provider/get/employee/remote";

        // 3. 通过RestTemplate调用远程微服务
        return restTemplate.getForObject(host + url, Employee.class);
    }
}

application.yml

resources/application.yml

server:
  port: 4000

spring:
  application:
    name: atyuanbaoqiang-consumer

eureka:
  client:
    service-url:
      defaultZone: http://localhost:5000/eureka/

gradle-spring-cloud-provider

依赖部分

archivesBaseName = 'provider'
bootJar {
    archiveClassifier = 'boot'
}
dependencies {
    implementation project(':gradle-spring-cloud-common') /* 子模块之间的依赖 */
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' // eureka 客户端依赖
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

主启动类

com.yuanbaoqiang.spring.cloud.ProviderMainType

package com.yuanbaoqiang.spring.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 14:14
 */
// 下面两个注解功能大致相同,较低版本必须使用
//@EnableDiscoveryClient  启用发现服务功能,不局限于Eureka注册中心
//@EnableEurekaClient     启用Eureka客户端功能
@SpringBootApplication
public class ProviderMainType {
    public static void main(String[] args) {
        SpringApplication.run(ProviderMainType.class, args);
    }
}

Handler方法

package com.yuanbaoqiang.spring.cloud.handler;

import com.yuanbaoqiang.spring.cloud.entity.Employee;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 14:52
 */
@RestController
public class EmployeeHandler {
    @RequestMapping("/provider/get/employee/remote")
    public Employee getEmployeeRemote(HttpServletRequest request) {
        // 获取当前服务的端口号
        int serverPort = request.getServerPort();


        return new Employee(555, "tom555 " + serverPort, 555.55);
    }
}

application.yml

resources/application.yml

server:
  port: 3000


eureka:
  client:
    service-url:    # 配置当前微服务作为Eureka客户端访问Eureka服务器端时访问的地址
      defaultZone: http://localhost:5000/eureka/


spring:
  application:
    name: atyuanbaoqiang-provider  # 指定当前微服务的名称,以便将来通过微服务名称调用微服务时可以找到

gradle-spring-cloud-eureka

依赖部分

archivesBaseName = 'eureka'
bootJar {
    archiveClassifier = 'boot'
}
dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' // eureka服务端依赖
}

主启动类

package com.yuanbaoqiang.spring.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @description:
 * @author: YuanbaoQiang
 * @time: 2020/12/3 17:58
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerMainType {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerMainType.class, args);
    }
}

application.yml

resources/application.yml

server:
  port: 5000

eureka:
  instance:
    hostname: localhost            # 配置当前Eureka服务的主机地址

  client:
    register-with-eureka: false    # 自己就是注册中心,所以自己不注册自己
    fetch-registry: false          # 自己就是注册中心,所以不需要从注册中取回信息
    service-url:                   # 客户端(指consumer和provider)访问Eureka所使用的地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

测试

开启Eureka注册中心服务

http://localhost:5000/

Gradle-SpringCloud聚合项目配置

此时的Application处没有微服务,说明还没有开启,之后开启相应的服务:

开启3个Porvider服务(端口号分别为1000,2000,3000)和Consumer,刷新后显示:

Gradle-SpringCloud聚合项目配置

在Consumer中调用Provider提供的方法,返回信息成功!
http://localhost:4000/consumer/ribbon/get/employee
Gradle-SpringCloud聚合项目配置