spring-cloud Feign

在spring cloud体系中,各个微服务都是通过http接口的形式暴露自身服务的,因此在调用远程服务时需要用到http客户端。

Feign是一种声明式、模板化的HTTP客户端,在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。Feign和JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate类似,只是用起来更简单,优雅。

简单示例:

新建服务: feign-client

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 http://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.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>feign-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>feign-client</name>
    <description>Demo project for Spring Boot</description>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-web</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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

application.yml配置如下:

server:
  port: 7003

spring:
  application:
    name: feign-client

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:7000/eureka/
  instance:
    lease-expiration-duration-in-seconds: 2
    #服务刷新时间配置,每隔这个时间会主动心跳一次
    #默认30s
    lease-renewal-interval-in-seconds: 1
    #将ip注册到eureka server上而不是机器主机名
    prefer-ip-address: true
    #ip-address: 127.0.0.1
    #InstanceId默认是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}},
    #也就是:主机名:应用名:应用端口
    #通过instance-id 自定义ip+端口号
    instance-id: ${spring.cloud.client.ipaddress}:${server.port}

这里需要用到eureka

通过@EnableFeignClients 开启Feign:

package com.example.feignclient;

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
@EnableFeignClients
@EnableEurekaClient
public class FeignClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignClientApplication.class, args);
    }

}

为了让Feign知道在调用方法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义一个接口

package com.example.feignclient;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Created by gexiaoshan on 2019/1/17.
 * Feign的客户端接口定义
 */
@FeignClient("eureka-discovery")
public interface TestHttpClient {

    @GetMapping("/test")
    String test();
}

@FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。

本列中"eureka-discovery" 是注册在eureka中的服务。

@GetMapping("/test") 表示在调用该方法时,向服务eureka-discovery的/test接口发出get请求。

新建一个测试controller:

package com.example.feignclient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by gexiaoshan on 2019/1/15.
 */
@RestController
public class TestController {

    @Autowired
    TestHttpClient testHttpClient;

    @RequestMapping("/test")
    public String getTest(){
        return testHttpClient.test();
    }
}

启动eureka-server, eureka-discovery ,feign-client。

测试:http://localhost:7003/test

返回:eureka-discovery

这里有个问题,在引jar时开始没有引入:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在启动时会自动关闭服务,至于为什么还有待研究。

gitHub : https://github.com/gexiaoshan518/spring-cloud.git

欢迎扫码交流:

原文地址:https://www.cnblogs.com/gexiaoshan/p/10283510.html