SpringCloud服務消費的幾種方式
以下示例代碼均基於consul註冊中心
一、使用LoadBalancerClient
LoadBalancerClient接口的命名中,可以看出這是一個負載均衡客戶端的抽象定義,spring提供了一個實現
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wzl.springcloud</groupId>
<artifactId>services-cousmer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>services-consume</name>
<description>Demo project for Spring Boot</description>
<properties>
<!-- 版本管理 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.version>4.12</junit.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、application.yml
server:
#服務端口號
port: 8080
spring:
application:
#服務名稱
name: services-consume
thymeleaf:
cache: false
cloud:
consul:
host: 192.168.12.125
port: 8500
discovery:
#是否需要註冊到consul中
register: true
#服務地址直接爲IP地址
hostname: 192.168.12.1
management:
endpoints:
web:
exposure:
include: '*'
3、啓動類
package com.wzl.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ServicesConsumeApplication {
public static void main(String[] args) {
SpringApplication.run(ServicesConsumeApplication.class, args);
}
}
4、相關實現類
package com.wzl.springcloud.basic.report.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
@RestController
public class ReportController {
@Autowired
private WeatherReportService weatherReportService;
@RequestMapping("/report/getDataByCities")
public List<City> getDataByCities() {
return weatherReportService.getDataByCities();
}
}
package com.wzl.springcloud.basic.report.vo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
//聲明爲xml的根元素
@XmlRootElement(name = "d")
// 聲明xml的訪問類型爲FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {
// 聲明爲xml的屬性
@XmlAttribute(name = "d1")
private String cityId;
// 聲明爲xml的屬性
@XmlAttribute(name = "d2")
private String cityName;
// 聲明爲xml的屬性
@XmlAttribute(name = "d3")
private String cityCode;
// 聲明爲xml的屬性
@XmlAttribute(name = "d4")
private String province;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
package com.wzl.springcloud.basic.report.service;
import java.util.List;
import com.wzl.springcloud.basic.report.vo.City;
public interface WeatherReportService {
// 獲取所有城市列表
List<City> getDataByCities();
}
package com.wzl.springcloud.basic.report.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
/**
* LoadBalancer客戶端
*/
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
@Autowired
private LoadBalancerClient loadBalancer;
// 城市服務的服務名
private static final String CITY_SERVICE_NAME = "vis-basic-city";
@Override
public List<City> getDataByCities() {
List<City> cityList = null;
ServiceInstance serviceInstance = loadBalancer.choose(CITY_SERVICE_NAME);
String uri = serviceInstance.getUri().toString() + "/cities/getList";
// 調用服務接口來獲取
ResponseEntity<String> respString = new RestTemplate().getForEntity(uri, String.class);
// 判斷ResponseEntity的狀態碼是否爲200,爲200時取出strBody
if (respString.getStatusCodeValue() == 200) {
String jsonStr = respString.getBody();
cityList = JSON.parseArray(jsonStr, City.class);
}
return cityList;
}
}
二、使用Ribbon
Spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端負載均衡的工具。它是一個基於HTTP和TCP的客戶端負載均衡器。它可以通過在客戶端中配置ribbonServerList來設置服務端列表去輪詢訪問以達到均衡負載的作用。
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wzl.springcloud</groupId>
<artifactId>services-cousmer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>services-consume</name>
<description>Demo project for Spring Boot</description>
<properties>
<!-- 版本管理 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.version>4.12</junit.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、application.yml
server:
#服務端口號
port: 8080
spring:
application:
#服務名稱
name: services-consume
thymeleaf:
cache: false
cloud:
consul:
host: 192.168.12.125
port: 8500
discovery:
#是否需要註冊到consul中
register: true
#服務地址直接爲IP地址
hostname: 192.168.12.1
management:
endpoints:
web:
exposure:
include: '*'
3、啓動類 & RestConfiguration
package com.wzl.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ServicesConsumeApplication {
public static void main(String[] args) {
SpringApplication.run(ServicesConsumeApplication.class, args);
}
}
package com.wzl.springcloud.basic.report.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
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;
@Configuration
public class RestConfiguration {
@Autowired
private RestTemplateBuilder builder;
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return builder.build();
}
}
@LoadBalanced註解表明這個restRemplate開啓負載均衡的功能,用LoadBalancerClient配置,並且會替換URL中的服務名稱爲具體的IP地址
4、相關實現類
package com.wzl.springcloud.basic.report.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
@RestController
public class ReportController {
@Autowired
private WeatherReportService weatherReportService;
@RequestMapping("/report/getDataByCities")
public List<City> getDataByCities() {
return weatherReportService.getDataByCities();
}
}
package com.wzl.springcloud.basic.report.vo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
//聲明爲xml的根元素
@XmlRootElement(name = "d")
// 聲明xml的訪問類型爲FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {
// 聲明爲xml的屬性
@XmlAttribute(name = "d1")
private String cityId;
// 聲明爲xml的屬性
@XmlAttribute(name = "d2")
private String cityName;
// 聲明爲xml的屬性
@XmlAttribute(name = "d3")
private String cityCode;
// 聲明爲xml的屬性
@XmlAttribute(name = "d4")
private String province;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
package com.wzl.springcloud.basic.report.service;
import java.util.List;
import com.wzl.springcloud.basic.report.vo.City;
public interface WeatherReportService {
// 獲取所有城市列表
List<City> getDataByCities();
}
package com.wzl.springcloud.basic.report.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
/**
* Ribbon客戶端
*/
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
@Autowired
// 對rest客戶端的封裝
private RestTemplate restTemplate;
// 城市服務的服務名
private static final String CITY_SERVICE_NAME = "vis-basic-city";
@Override
public List<City> getDataByCities() {
List<City> cityList = null;
String uri = "http://" + CITY_SERVICE_NAME + "/cities/getList";
// 調用服務接口來獲取
ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);
// 判斷ResponseEntity的狀態碼是否爲200,爲200時取出strBody
if (respString.getStatusCodeValue() == 200) {
String jsonStr = respString.getBody();
cityList = JSON.parseArray(jsonStr, City.class);
}
return cityList;
}
}
三、使用Feign
Feign是一個聲明性的web服務客戶端,它使編寫web服務客戶機變得更容易。
總結特點:
1、Feign採用的是接口加註解,就像調用本地方法一樣調用遠程服務
2、Feign整合了Ribbon,當你使用@FeignClient,Ribbon自動被應用,所以也會負載均衡
3、Feign是一種聲明式、模板化的HTTP客戶端。
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wzl.springcloud</groupId>
<artifactId>services-cousmer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>services-consume</name>
<description>Demo project for Spring Boot</description>
<properties>
<!-- 版本管理 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.version>4.12</junit.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、application.yml
server:
#服務端口號
port: 8080
spring:
application:
#服務名稱
name: services-consume
thymeleaf:
cache: false
cloud:
consul:
host: 192.168.12.125
port: 8500
discovery:
#是否需要註冊到consul中
register: true
#服務地址直接爲IP地址
hostname: 192.168.12.1
management:
endpoints:
web:
exposure:
include: '*'
3、啓動類
package com.wzl.springcloud.basic.report;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class ReportServerApplication {
public static void main(String[] args) {
SpringApplication.run(ReportServerApplication.class, args);
}
}
4、相關實現類
package com.wzl.springcloud.basic.report.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
@RestController
public class ReportController {
@Autowired
private WeatherReportService weatherReportService;
@RequestMapping("/report/getDataByCities")
public List<City> getDataByCities() {
return weatherReportService.getDataByCities();
}
}
package com.wzl.springcloud.basic.report.vo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
//聲明爲xml的根元素
@XmlRootElement(name = "d")
// 聲明xml的訪問類型爲FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {
// 聲明爲xml的屬性
@XmlAttribute(name = "d1")
private String cityId;
// 聲明爲xml的屬性
@XmlAttribute(name = "d2")
private String cityName;
// 聲明爲xml的屬性
@XmlAttribute(name = "d3")
private String cityCode;
// 聲明爲xml的屬性
@XmlAttribute(name = "d4")
private String province;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
package com.wzl.springcloud.basic.report.feign;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import com.wzl.springcloud.basic.report.vo.City;
@FeignClient(name = "vis-basic-city")
@RequestMapping("/cities")
public interface CityApiFeign {
@RequestMapping("/getList")
public List<City> listCity();
}
package com.wzl.springcloud.basic.report.service;
import java.util.List;
import com.wzl.springcloud.basic.report.vo.City;
public interface WeatherReportService {
// 獲取所有城市列表
List<City> getDataByCities();
}
package com.wzl.springcloud.basic.report.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wzl.springcloud.basic.report.feign.CityApiFeign;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
/**
* Feign客戶端
*/
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
@Autowired
private CityApiFeign cityApiFeign;
@Override
public List<City> getDataByCities() {
return cityApiFeign.listCity();
}
}
四、通過網關調用服務
在微服務框架中,每個對外服務都是獨立部署的,對外的API或者服務地址都不是不盡相同的。對於內部而言,很簡單,通過註冊中心自動感知即可。但我們大部分情況下,服務都是提供給外部系統進行調用的,不可能同享一個註冊中心。同時一般上內部的微服務都是在內網的,和外界是不連通的。而且,就算我們每個微服務對外開放,對於調用者而言,調用不同的服務的地址或者參數也是不盡相同的,這樣就會造成消費者客戶端的複雜性,同時想想,可能微服務可能是不同的技術棧實現的,有的是http、rpc或者websocket等等,也會進一步加大客戶端的調用難度。所以,一般上都有會有個api網關,根據請求的url不同,路由到不同的服務上去,同時入口統一了,還能進行統一的身份鑑權、日誌記錄、分流等操作。接下來就是基於zuul的服務調用。
需要提前搭建好網關服務,以下示例代碼基於zuul網關
1、網關zuul的application.yml配置
server:
#服務端口號
port: 7070
spring:
application:
#服務的名稱
name: vis-basic-zuul
#指定註冊中心地址
cloud:
consul:
host: 192.168.12.125
port: 8500
discovery:
#是否需要註冊到consul中
register: true
#服務地址直接爲IP地址
hostname: 192.168.12.1
service-name: ${spring.application.name}
healthCheckPath: /actuator/health
healthCheckInterval: 15s
zuul:
#表示不暴露配置之外的服務
ignored-services: '*'
routes:
#天氣服務
vis-basic-weather:
path: /api-weather/**
service-id: vis-basic-weather
#城市服務
vis-basic-city:
path: /api-city/**
service-id: vis-basic-city
2、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>
<groupId>com.wzl.springcloud</groupId>
<artifactId>services-cousmer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>services-consume</name>
<description>Demo project for Spring Boot</description>
<properties>
<!-- 版本管理 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.version>4.12</junit.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、application.yml
server:
#服務端口號
port: 8080
spring:
application:
#服務名稱
name: services-consume
thymeleaf:
cache: false
cloud:
consul:
host: 192.168.12.125
port: 8500
discovery:
#是否需要註冊到consul中
register: true
#服務地址直接爲IP地址
hostname: 192.168.12.1
management:
endpoints:
web:
exposure:
include: '*'
4、啓動類
package com.wzl.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class ServicesConsumeApplication {
public static void main(String[] args) {
SpringApplication.run(ServicesConsumeApplication.class, args);
}
}
5、相關實現類
package com.wzl.springcloud.basic.report.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
@RestController
public class ReportController {
@Autowired
private WeatherReportService weatherReportService;
@RequestMapping("/report/getDataByCities")
public List<City> getDataByCities() {
return weatherReportService.getDataByCities();
}
}
package com.wzl.springcloud.basic.report.vo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
//聲明爲xml的根元素
@XmlRootElement(name = "d")
// 聲明xml的訪問類型爲FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {
// 聲明爲xml的屬性
@XmlAttribute(name = "d1")
private String cityId;
// 聲明爲xml的屬性
@XmlAttribute(name = "d2")
private String cityName;
// 聲明爲xml的屬性
@XmlAttribute(name = "d3")
private String cityCode;
// 聲明爲xml的屬性
@XmlAttribute(name = "d4")
private String province;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
package com.wzl.springcloud.basic.report.feign;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import com.wzl.springcloud.basic.report.vo.City;
@FeignClient(name = "vis-basic-zuul")
@RequestMapping("/api-city/cities")
public interface CityApiFeignGateway {
@RequestMapping("/getList")
public List<City> listCity();
}
package com.wzl.springcloud.basic.report.service;
import java.util.List;
import com.wzl.springcloud.basic.report.vo.City;
public interface WeatherReportService {
// 獲取所有城市列表
List<City> getDataByCities();
}
package com.wzl.springcloud.basic.report.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wzl.springcloud.basic.report.feign.CityApiFeignGateway;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;
/**
* FeignGateway客戶端
*/
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
@Autowired
private CityApiFeignGateway cityApiFeignGateway;
@Override
public List<City> getDataByCities() {
return cityApiFeignGateway.listCity();
}
}