知識庫 / Spring / Spring Cloud RSS 訂閱

配置 Spring Cloud FeignClient URL

Spring Cloud
HongKong
10
11:41 AM · Dec 06 ,2025

1. 引言

在本文中,我們將探討如何向 Feign 客户端接口提供目標 URL。

2. 概述

為了快速上手,我們將使用來自 JSONPlaceholder 網站的模擬響應,用於 Albums, Posts,Todos 對象。

讓我們查看 Album 類:

public class Album {
    
    private Integer id;
    private Integer userId;
    private String title;
    
   // standard getters and setters
}

以及 Post 類:

public class Post {
    
    private Integer id;
    private Integer userId;
    private String title;
    private String body;
    
    // standard getters and setters
}
<p>最後,<em data-translation-key="Todo.class">Todo</em> 類:</p>
public class Todo {
    
    private Integer id;
    private Integer userId;
    private String title;
    private Boolean completed;
    
    // standard getters and setters
}

3. 在標註中添加基本 URL

我們可以通過在客户端接口的@FeignClient註解中的url屬性來設置基本 URL。 隨後,我們將使用相關的 HTTP 謂詞對方法進行標註,並添加所需的端點:

@FeignClient(name = "albumClient", url = "https://jsonplaceholder.typicode.com/albums/")
public interface AlbumClient {
    
    @GetMapping(value = "/{id}")
    Album getAlbumById(@PathVariable(value = "id") Integer id);
}

讓我們添加一個 REST 控制器來測試我們的客户端:

@RestController
public class ConfigureFeignUrlController {
    
    private final AlbumClient albumClient;
    // standard constructor
    
    @GetMapping(value = "albums/{id}")
    public Album getAlbumById(@PathVariable(value = "id") Integer id) {
        return albumClient.getAlbumById(id);
    }
    
   // other controller methods
}

此選項在目標 URL 在應用程序的整個生命週期內保持不變時非常有用。

4. 使用配置屬性

或者,對於 Spring Cloud 版本 2022.0.1 或更高版本,我們可以使用 application.properties 來提供 Feign Client 接口的 URL。該屬性為 spring.cloud.openfeign.client.config.<接口名稱>.url。 其中,<接口名稱> 是我們在 @FeignClient 註解中提供的 name 屬性的值。

@FeignClient(name = "postClient")
public interface PostClient {
    
    @GetMapping(value = "/{id}")
    Post getPostById(@PathVariable(value = "id") Integer id);
}

我們將在應用程序中添加基本 URL:

spring.cloud.openfeign.client.config.postClient.url=https://jsonplaceholder.typicode.com/posts/

對於 Spring Cloud 版本低於 2022.0.1,我們可以將 url 屬性設置為 @FeignClient 以從 application.properties 中讀取值。

@FeignClient(name = "postClient", url = "${spring.cloud.openfeign.client.config.postClient.url}")

接下來,讓我們將這個客户端注入我們之前創建的控制器中:

@RestController
public class FeignClientController {
    private final PostClient postClient;
    
    // other attributes and standard constructor
    
    @GetMapping(value = "posts/{id}")
    public Post getPostById(@PathVariable(value = "id") Integer id) {
        return postClient.getPostById(id);
    }
    
   // other controller methods
}

此選項在目標 URL 根據應用程序的環境而變化時非常有用。例如,我們可能在開發環境中使用模擬服務器,而在生產環境中則使用實際服務器。

5. 使用 RequestLine

Spring Cloud 提供了一個功能,允許我們覆蓋目標 URL 或在運行時直接提供 URL。 這通過使用 @RequestLine 標註並使用 Feign Builder API 手動創建 Feign 客户端來實現:

@FeignClient(name = "todoClient")
public interface TodoClient {
    
    @RequestLine(value = "GET")
    Todo getTodoById(URI uri);
}

我們必須手動創建這個 feign 客户端,在我們的控制器中:

@RestController
@Import(FeignClientsConfiguration.class)
public class FeignClientController {
    
    private final TodoClient todoClient;
    
    // other variables
    
    public FeignClientController(Decoder decoder, Encoder encoder) {
        this.todoClient = Feign.builder().encoder(encoder).decoder(decoder).target(Target.EmptyTarget.create(TodoClient.class));
        // other initialisation
   }
    
    @GetMapping(value = "todo/{id}")
    public Todo getTodoById(@PathVariable(value = "id") Integer id) {
        return todoClient.getTodoById(URI.create("https://jsonplaceholder.typicode.com/todos/" + id));
    }
    
    // other controller methods
}

在這裏,我們首先通過 FeignClientsConfiguration.class 導入默認的 Feign 客户端配置。 Feign.Builder 用於自定義 API 接口的這些屬性。我們可以配置諸如 encoderdecoderconnectTimeoutreadTimeout、認證等屬性。

target 屬性定義這些屬性將應用於哪個接口。該接口有兩項實現:EmptyTarget,我們在此處使用了它,以及 HardCodedTarget

EmptyTarget 類在編譯時不需要 URL,而 HardCodedTarget 則需要。

值得注意的是,作為參數提供的 URI 將覆蓋在 @feignClient 註解中提供的 URL,以及配置屬性中提供的 URL。 同樣,在 @FeignClient 註解中提供的 URL 將覆蓋配置屬性中提供的 URL。

6. 使用 RequestInterceptor

另一種在運行時提供目標 URL 的方法是向 Feign.Builder 提供自定義 RequestInterceptor。在這裏,我們將覆蓋 RestTemplatetarget 屬性,將其 URL 更新為通過 requestInterceptorFeign.Builder 提供的 URL:

public class DynamicUrlInterceptor implements RequestInterceptor {
    private final Supplier<String> urlSupplier;
    // standard constructor

    @Override
    public void apply(RequestTemplate template) {
        String url = urlSupplier.get();
        if (url != null) {
            template.target(url);
        }
    }
}

讓我們為 AlbumClient.java 添加另一個方法:

@GetMapping(value = "/{id}")
Album getAlbumByIdAndDynamicUrl(@PathVariable(name = "id") Integer id);

與其在構造函數中使用 Builder,我們將在 ConfigureFeignUrlController 的一個方法中創建 AlbumClient 的實例:

@RestController
@Import(FeignClientsConfiguration.class)
public class ConfigureFeignUrlController {
    
    private final ObjectFactory<HttpMessageConverters> messageConverters;
    
    private final ObjectProvider<HttpMessageConverterCustomizer> customizers;
    
    // other variables, standard constructor and other APIs
    
    @GetMapping(value = "/dynamicAlbums/{id}")
    public Album getAlbumByIdAndDynamicUrl(@PathVariable(value = "id") Integer id) {
        AlbumClient client = Feign.builder()
          .requestInterceptor(new DynamicUrlInterceptor(() -> "https://jsonplaceholder.typicode.com/albums/"))
          .contract(new SpringMvcContract())
          .encoder(new SpringEncoder(messageConverters))
          .decoder(new SpringDecoder(messageConverters, customizers))
          .target(Target.EmptyTarget.create(AlbumClient.class));
     
        return client.getAlbumByIdAndDynamicUrl(id);
    }
}

在這裏,我們添加了上面創建的 DynamicUrlInterceptor,它接受一個 URL 以覆蓋 AlbumClient 的默認 URL。我們還配置客户端使用 SpringMvcContract, SpringEncoderSpringDecoder

這兩個選項將對我們在應用程序中提供 Webhook 支持非常有用,因為每個客户端的目標 URL 可能會有所不同。

7. 結論

在本文中,我們瞭解到如何通過多種方式配置 Feign Client 接口的目標 URL。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.