Gradle-SpringCloud聚合项目配置
版本信息
- idea2020
- jdk-1.8
- gradle-6.7.1
gradle
gradle 和 maven的简单对比
详情见:Gradle vs Maven Comparison
单一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
- Gradle Wrapper执行后生成的文件夹
- Gradle Wrapper的启动脚本
- 用于定义生成名称和子项目的设置文件
- 项目程序的构建脚本
- 默认的Java资源文件夹
- 默认的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
打包的测试(相关设置细节在后续章节)
可以单独在不同的子模块中进行一个小小的打包测试(如果执行的是父类工程中的Task命令,则对当前整个项目都有效!):
对于consumer,我开启了jar,没有禁用bootjar,也就是说可以同时打出jar包和bootjar包:
在子模块下的build文件夹中的libs文件夹中找到打出的jar包和bootJar包:
在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
orbootWar
tasks are configured, thejar
orwar
tasks are disabled. A project can be configured to build both an executable archive and a normal archive at the same time by enabling thejar
orwar
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文件夹)
并且在输出窗口中也可以看到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/
此时的Application处没有微服务,说明还没有开启,之后开启相应的服务:
开启3个Porvider服务(端口号分别为1000,2000,3000)和Consumer,刷新后显示:
在Consumer中调用Provider提供的方法,返回信息成功!
http://localhost:4000/consumer/ribbon/get/employee