不同的springboot对应的springcloud版本可能不一样,就拿springboot2.1.7或者2.1.8来说,它对应的springcloud版本是Greenwich.SR3。这些对应的版本信息都是从官方文档中所得知,所以要养成翻阅官方文档的好习惯。
为什么需要搭建一个父maven项目,直接创建多个springboot项目不好吗?其实对学习而言都差不多,但是父maven项目它可以把子项目中出现多次的maven坐标统一由父项目管理,然后子项目继承父项目就可以得到父项目中的maven坐标了,这样子不香吗。
以下是我的项目目录。
为了美观,我甚至把父maven的src路径都给删了。
介绍一下每一个子项目:
common:这个项目放的是给所有项目提供公共类的项目。
customer:消费者,调用注册进注册中心的提供者服务。
provider:提供者,将自己的服务注册进注册中心,供消费者调用。
server:eureka注册中心,里面注册着需要被调用的服务,甚至注册中心也可以注册注册中心,再通过某些配置来达成集群的效果。
废话不多说,来看看父项目里的pom.xml里面都有哪些maven坐标。
<?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.qiu</groupId>
<artifactId>boot2cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>boot2cloud Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>server</module>
<module>provider</module>
<module>customer</module>
<module>common</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>boot2cloud</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
可以看到,该pom中有营养的坐标就两个:spring-cloud-dependencies和spring-boot-starter-parent,只要子项目继承了父项目,那么后续中这两个坐标都可以不用写了,当然写了也无妨。
Eureka它也是一个springboot项目,所以它只要继承了父项目就不需要引入springboot坐标了。
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qiu</groupId>
<artifactId>boot2cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.qiu</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
eureka与业务不相关,其实它的test相关坐标可以删掉。说实话,我甚至把eureka项目中的测试文件给删掉了。
接下来就是配置yml文件,只需要配置这个,其他的都不需要管。
application.yml内容如下
server:
port: 8761//默认端口
spring:
application:
name: server-eureka//服务名,最好写,方便识别
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/ //Eureka注册中心的路径
register-with-eureka: false //不把自己注册进eureka
fetch-registry: false //不从eureka中获取注册信息
最后在启动类上添加@EnableEurekaServer注解,表示开启eureka服务,换句话说就是宣言自己是注册中心。
所有操作完毕后启动项目,然后在浏览器地址栏输入网址:localhost:8761
提供者并不是指只提供服务,他也可以作为消费者。
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qiu</groupId>
<artifactId>boot2cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.qiu</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.qiu</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
陌生坐标介绍:
spring-cloud-starter-netflix-eureka-client:一定要与spring-cloud-starter-netflix-eureka-server区分开来,一个是客户端(消费者、提供者)相关依赖,一个是eureka注册中心相关依赖。
spring-cloud-starter-openfeign:这是一种获得服务的方式,也叫声明式REST调用,是目前企业中用的最多的方式,当然还有种方式是RestTemplate。RestTemplate是Springboot自带的,无需引入其他坐标。
spring-boot-starter-actuator:监测相关依赖,如果不想关注服务健康程度之类的,可以把这个坐标给删了。
common:它是父项目中的一个子项目.
因为在父项目中这个标签的缘故,所以只要子项目引入了common依赖坐标就可以使用这个common项目中的类了。
提供者的yml文件配置
server:
port: 8081
spring:
application:
name: provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
因为需要被消费者所知道,所以必须要把自己注册进Eureka中
在启动类开启相关注解
写一些接口,供消费者调用,启动服务
@RestController
public class TestController {
@RequestMapping(value = "/test")
public String firstCloud(int id){
People people = new People();
people.setId(id);
people.setName("hello");
return people.toString();
}
@RequestMapping(value = "/test2")
public String secondCloud(@RequestBody People people){
//必须要有@RequestBody
return people.toString();
}
}
启动服务后结果
红框中已经多出了一个注册进去的服务,然后消费者只要通过Feign声明式调用REST就可以获得提供者项目中接口返回的值了。
消费者和提供者其实就是一个东西吗,消费者消费别人提供的服务的同时,本身也可以将自己注册进Eureka供其他的消费者来调用。
maven坐标一样,启动类的注解也一样,yml也差不多。
使用Feign去调用其他人注册进Eureka的服务。
第一步:在启动类上添加@EnableFeignClients(提供者也添加过了)
第二步:yml配置
server:
port: 8082
spring:
application:
name: customer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
如果单纯的只是想消费,可以不把自己注册进eureka。
第三步:添加feign接口与控制层
@FeignClient("provider")
public interface TestFeignClient {
@RequestMapping(value = "/test")
String getPeopleString(@RequestParam("id")int id);//必须要有@RequestParam
@RequestMapping(value = "/test2")
String getPeople(@RequestBody People people);//必须要有@RequestBody
}
@FeignClient(“provider”)中的provider是需要调用的服务的项目名,在eureka上是大写。大小写不区分。
该接口中@RequestMapping(value = “/test”)则是提供者项目中的映射路径。
当消费者的控制层将这个接口自动注入了,调用方法体及传入参数的时候,它的返回值就是提供者的返回值。
第四部:添加控制层
@RestController
public class CusController {
@Autowired
TestFeignClient testFeignClient;
@RequestMapping(value = "/getPeopleString")
public String getPeople(int id){
String people = testFeignClient.getPeopleString(id);
return people;
}
@RequestMapping(value = "/getPeople")
public String getPeople(@RequestBody People people){
//必须要有@RequestBody
String people1 = testFeignClient.getPeople(people);
return people1;
}
}
就拿映射路径为/getPeople的接口来说,它的结果如下图所示。
以上,就是简单的springcloud应用,有兴趣的伙伴可以上spring的官网去了解,有好多组件。