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

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

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

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

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

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

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

<?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>

配置文件作相關配置apache

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在遠程調用失敗後會進行重試。app

@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工程的實例,端口號876二、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

 

相關文章
相關標籤/搜索