SpringCloud之Feign:REST客戶端

在Spring Cloud集羣中,各個角色的通訊基於REST服務,在調用服務時,須要使用REST客戶端,經常使用,除了使用Spring自帶的RestTemplate,也可以使用另外一個REST客戶端:Feign。html

使用Feign時,能夠使用自帶註解或第三方註解來修飾接口,使得接口具備訪問Web Service的能力。
Feign還支持插件式的編碼器和解碼器,對請求和響應進行不一樣的封裝和解析。
Spring Cloud將Feign集成到Netflix項目中,與Eureka、Ribbon集成時,Feign就具備負載均衡的功能。
Feign在Spring Boot Web項目的使用例子可參考:《Spring Boot 2 發佈與調用REST服務

java

下面例子爲在Spring Cloud的使用。
開發工具:IntelliJ IDEA 2019.2.3web

1、服務器端spring

一、建立項目apache

IDEA中建立一個新的SpringBoot項目,名稱爲「spring-feign-server」,SpringBoot版本選擇2.1.10,在選擇Dependencies(依賴)的界面勾選Spring Cloud Discovert ->
Eureka Server,建立完成後的pom.xml配置文件自動添加SpringCloud最新穩定版本依賴,當前爲Greenwich.SR3。
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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-feign-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-feign-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <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>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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>
View Code

二、修改配置application.yml服務器

修改端口號爲8761;取消將本身信息註冊到Eureka服務器,不從Eureka服務器抓取註冊信息。app

server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

三、修改啓動類代碼SpringFeignServerApplication.java負載均衡

增長註解@EnableEurekaServermaven

package com.example.springfeignserver;

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

@SpringBootApplication
@EnableEurekaServer
public class SpringFeignServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringFeignServerApplication.class, args);
    }
}

2、服務提供者

一、建立項目

IDEA中建立一個新的SpringBoot項目,除了名稱爲「spring-feign-provider」,其它步驟和上面建立服務器端同樣。

二、修改配置application.yml

spring:
  application:
    name: spring-feign-provider
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

三、添加一個實體類User.java

package com.example.springfeignprovider;

public class User {
    String name;
    Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

四、修改啓動類代碼SpringFeignProviderApplication.java

增長註解@EnableEurekaClient和@RestController;
讓類在啓動時讀取控制檯輸入,決定使用哪一個端口啓動服務器;
增長2個測試用的控制器方法。

package com.example.springfeignprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Scanner;

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringFeignProviderApplication {

    public static void main(String[] args) {
        //SpringApplication.run(SpringFeignProviderApplication.class, args);
        Scanner scan = new Scanner(System.in);
        String port = scan.nextLine();
        new SpringApplicationBuilder(SpringFeignProviderApplication.class).properties("server.port=" + port).run(args);
    }

    @RequestMapping("/hello")
    public String hello(HttpServletRequest request) {
        return "hello world." + request.getServerPort();
    }

    @RequestMapping(value="/user/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
    public User user(@PathVariable String name) {
        User u = new User();
        u.setName(name);
        u.setAge(30);
        return u;
    }
}

3、服務調用者

一、建立項目
IDEA中建立一個新的SpringBoot項目,名稱爲「spring-feign-invoker」,SpringBoot版本選擇2.1.10,在選擇Dependencies(依賴)的界面勾選Spring Cloud Discovert -> Eureka Server,Spring Cloud Routing -> OpenFeign。
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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-feign-invoker</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-feign-invoker</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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>
View Code

二、修改配置application.yml

server:
  port: 9000
spring:
  application:
    name: spring-feign-invoker
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

三、添加一個實體類User.java

package com.example.springfeigninvoker;

public class User {
    String name;
    Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

四、添加一個客戶端接口UserClient.java

package com.example.springfeigninvoker;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

//聲明調用的服務名稱
@FeignClient("spring-feign-provider")
public interface UserClient {
    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    String hello();

    @RequestMapping(method = RequestMethod.GET, value = "/user/{name}")
    User getUser(@PathVariable("name") String name);
}

五、修改啓動類代碼CloudInvokerApplication.java

增長註解@EnableEurekaClient和@EnableFeignClients。

package com.example.springfeigninvoker;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringFeignInvokerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringFeignInvokerApplication.class, args);
    }
}

六、添加控制器 InvokerController.java 

package com.example.springfeigninvoker;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Configuration
public class InvokerController {
    @Autowired
    private UserClient userClient;

    @RequestMapping(value = "/invokeHello", method = RequestMethod.GET)
    public String invokeHello(){
        return userClient.hello();
    }

    @RequestMapping(value = "/invokeUser", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String invokeUser(){
        return userClient.getUser("小明").getAge().toString();
    }
}

4、測試

一、啓動服務器端。
瀏覽器訪問http://localhost:8761/,正常
二、啓動兩個服務提供者,在控制檯中分別輸入8080和8081啓動。
(1)瀏覽器訪問 http://localhost:8080/user/小明
輸出:{"name":"小明","age":30}
(2)瀏覽器訪問 http://localhost:8081/user/小強
輸出:{"name":"小強","age":30}
三、啓動服務調用者。(1)瀏覽器訪問http://localhost:9000/invokeHello,頁面顯示在下面8080和8081端口之間切換:hello world.8080hello world.8081(2)瀏覽器訪問http://localhost:9000/invokeUser,輸出:30

相關文章
相關標籤/搜索