OpenFeign使用筆記


是什么

Feign是一個聲明式Web Service客戶端。使用Feign能讓編寫Web Service客戶端更加簡單, 它的使用方法是定義一個接口,然后在上面添加注解,同時也支持JAX-RS標准的注解。Feign也支持可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支持了Spring MVC標准注解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支持負載均衡。

怎么用

官方github項目(readme里寫得很詳細,代碼里還有示例)

我遇到的一些特殊請求:

(1)POST請求方式,但是請求參數放在查詢字符串里:

一般的查詢字符串添加可以用@QueryMap Map<String, Object>(為什么要用這個,因為不是用的spring cloud分支下封裝過的feign,不支持直接用spring的注解)

@RequestLine("POST /example/foo/token")
String getAccessToken(@QueryMap Map<String, Object> queryMap);

(2)查詢字符串里帶特殊拼接符號如加號(實現形如GET /Groups?filter=displayName+Eq+{roleName}的查詢): https://stackoverflow.com/questions/43868680/feign-client-does-not-resolve-query-parameter

@RequestLine("GET /Groups?filter={roleName}")
String isValidRole(@Param(value = "roleName", expander = PrefixExpander.class) String roleName);

static final class PrefixExpander implements Param.Expander {
    @Override
    public String expand(Object value) {
        return "displayName+Eq+" + value;
    }
}

(3)feign添加自定義httpheader:

@RequestLine("POST /add")
@Headers("TOKEN: {userToken}")
Response addRecord(RecordVO recordVO,
                              @Param("TOKEN") String userToken);

普通項目示例(<-這是一個原文鏈接,稍微修改了下)

maven依賴

<!-- open-feign -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.0.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>10.0.1</version>
</dependency>

自定義接口

import feign.Param;
import feign.RequestLine;

public interface RemoteService {
    
    @RequestLine("GET /users/list?name={name}")
    String getOwner(@Param(value = "name") String name);
}

通過@RequestLine指定HTTP協議及URL地址

配置類

RemoteService service = Feign.builder()
            .options(new Options(1000, 3500))
            .retryer(new Retryer.Default(5000, 5000, 3)).encoder(new GsonEncoder()).target(RemoteService.class, "http://127.0.0.1:8085");

options方法指定連接超時時長及響應超時時長,retryer方法指定重試策略,target方法綁定接口與服務端地址。返回類型為綁定的接口類型。

(ps.還可以指定其他的:比如

.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC))

調用:

String result = service.getOwner("scott");

與調用本地方法相同的方式調用feign包裝的接口,直接獲取遠程服務提供的返回值。

spring cloud 項目示例(<-這是一個原文鏈接) 

maven依賴 

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

在啟動類上加@EnableFeignClients

注解,如果你的Feign接口定義跟你的啟動類不在一個包名下,還需要制定掃描的包名@ EnableFeignClients(basePackages = "com.fangjia.api.client")

配置類

@Configuration
public class FeignConfiguration {
    @Bean  
    Logger.Level feignLoggerLevel() {  
        return Logger.Level.FULL;  
    }  
}

自定義接口

@FeignClient(value = "fangjia-fsh-house-service", path = "/house", configuration = FeignConfiguration.class, fallback = HouseRemoteClientHystrix.class)
public interface HouseRemoteClient {
    
    /**
     * 獲取企業下某用戶的有效房產信息
     * @param eid    企業編號
     * @param uid    用戶編號
     * @return
     */
    @GetMapping("/list/{eid}/{uid}")
    public HouseListDto hosueList(@PathVariable("eid")Long eid, @PathVariable("uid")String uid);    
    
    /**
     * 獲取房產詳細信息
     * @param houseId 房產編號
     * @return
     */
    @GetMapping("/{houseId}")
    public HouseInfoDto hosueInfo(@PathVariable("houseId")Long houseId);
    
}

熔斷回調處理

@Component
public class HouseRemoteClientHystrix implements HouseRemoteClient {

    @Override
    public HouseListDto hosueList(Long eid, String uid) {
        return new HouseListDto();
    }

    @Override
    public HouseInfoDto hosueInfo(Long houseId) {
        return new HouseInfoDto();
    }
}

原理(<-這是一個原文鏈接)

  1. 首先通過@EnableFeignCleints注解開啟FeignCleint
  2. 根據Feign的規則實現接口,並加@FeignCleint注解
  3. 程序啟動后,會進行包掃描,掃描所有的@ FeignCleint的注解的類,並將這些信息注入到ioc容器中。
  4. 當接口的方法被調用,通過jdk的代理,來生成具體的RequesTemplate
  5. RequesTemplate在生成Request
  6. Request交給Client去處理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
  7. 最后Client被封裝到LoadBalanceClient類,這個類結合類Ribbon做到了負載均衡。


免責聲明!

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



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