spring boot 2.0.3+spring cloud (Finchley)3、聲明式調用Feign


Feign受Retrofix、JAXRS-2.0和WebSocket影響,采用了聲明式API接口的風格,將Java Http客戶端綁定到他的內部。Feign的首要目標是將Java Http客戶端調用過程變得簡單。

源碼地址:https://github.com/OpenFeign/feign

本章案例基於上一章,可參考:

spring boot 2.0.3+spring cloud (Finchley)1、搭建Eureka 以及構建高可用Eureka Server集群 

spring boot 2.0.3+spring cloud (Finchley)2、搭建負載均衡Ribbon (Eureka+Ribbon+RestTemplate)

新建module工程eureka-feign-client。pom文件引入相關依賴,包括主maven工程的pom文件,eureka client起步依賴,feign的起步依賴,web的起步依賴(已在主maven工程pom中配置)

<?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.cralor</groupId>
    <artifactId>eureka-feign-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>eureka-feign-client</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.cralor</groupId>
        <artifactId>chap7-feign</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置文件做相關配置

server:
  port: 8765
spring:
  application:
    name: eureka-feign-client
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

在程序的啟動類加上注解@EnableFeignClients開啟Feign Client功能

@EnableFeignClients
@SpringBootApplication
public class EurekaFeignClientApplication {

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

通過以上步驟,該程序已經具備了Feign的功能,現在來實現一個簡單的feign client。新建一個EurekaClientFeign的接口,在接口上加@FeignClient注解來聲明一個Feign Client。value為遠程調用其他服務的服務名,FeignConfig.class為配置類,在EurekaClientFeign內部有一個sayHiFromClientEureka()的方法,該方法通過Feign來調用eureka-client服務的“/hi”的aipi接口。

@Component
@FeignClient(value = "eureka-client",configuration = FeignConfig.class)
public interface EurekaClientFeign {
    @GetMapping(value = "/hi")
    String sayHiFromClientEureka(@RequestParam(value = "name")String name);
}

在FeignConfig類上加上@Configuration注解,表明這是一個配置類,並注入一個BeanName為feignRetryer的Retryer的Bean。可使feign在遠程調用失敗后會進行重試。

@Configuration
public class FeignConfig {
    @Bean
    public Retryer feignRetryer(){
        return new Retryer.Default(100,TimeUnit.SECONDS.toMillis(1),5);
    }
}

service層HiService類注入EurekaClient的Bean

@Service
public class HiService {
    @Autowired
    EurekaClientFeign eurekaClientFeign;

    public  String sayHi(String name){
        return eurekaClientFeign.sayHiFromClientEureka(name);
    }
}

新建HiController類,調用HiService的sayHi()方法,HiService通過EurekaClientFeign遠程調用eureka-client服務的API接口“/hi”。

@RestController
public class HiController {
    @Autowired
    HiService hiService;

    @GetMapping("/hi")
    public String sayHi(@RequestParam(defaultValue = "cralor",required = false)String name){
        return hiService.sayHi(name);
    }
}

啟動eureka-server工程,端口號8761,啟動兩個eureka-client工程的實例,端口號8762、8763,啟動eureka-feign-client工程,端口號8765。在瀏覽器多次訪問http://localhost:8765/hi,瀏覽器會輪流顯示

            

可見Feign Client遠程調用了eureka-client的服務(存在端口號為8762和8763的兩個實例)的“/hi”API接口,feign client有負載均衡的能力。

 

總結:feign源碼實現過程如下

1.首先通過@EnableFeignClients注解開啟FeignClient功能。只有這個注解的存在,程序啟動時才會開啟對@FeignConfig注解的包的掃描,

2.根據Feig的規則實現接口,並在接口上面加上@FeignClient注解。

3.程序啟動后會進行包掃描,掃描所有@FeignClient注解的類,並將這些信息注入IOC容器中。

4.當接口的方法被調用時,通過JDK的代理來生成具體的RequestTemplate模板對象。

5.根據RequestTemplate再生成Http請求的Request對象。

6.Request對象交給Client去處理,其中Client的網絡請求框架可以是HttpURLConnection、HttpClient和OkHttp。

7.最后Client被封裝到LoadBalanceClient類,這個類結合類Ribbon做到了負載均衡。

 

 參考:https://windmt.com/2018/04/15/spring-cloud-3-service-producer-and-consumer/#Spring-Cloud-Feign

 

 案例代碼地址:https://github.com/cralor7/springcloud

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM