본문 바로가기
dev/spring

Spring HttpServiceProxyFactory를 사용하여 설정 오버헤드 줄이기

by igooo 2026. 9. 2.
728x90

개요

Spring Framework 6에는 @HttpExchnage 어노테이션을 사용하여 Java Interface를 통해 HTTP Client 서비스를 정의하는 기능이 추가되었다. 예를 들면 다음과 같다.

public interface UserService {
    @GetExchange("/users/{id}")
    User getUSer(@PathVariable String id);
}

 

UserSerivce HTTP 요청을 사용하기 위해서는 아래와 같이 Interface로부터 Proxy를 생성해야 사용이 가능하다.

// Initialize HTTP client
var restClient = RestClient.create("https://api.igooo.org");

// Create factory for client proxies
var proxyFactory = HttpServiceProxyFactory.builder()
    .exchangeAdapter(RestClientAdapter.create(restClient))
    .build();
    
// Create client proxy
var client = proxyFactory.createClient(UserService.class);

// Use proxy for HTTP requests
var user = clent.getUser("igooo");

 

HTTP Interface가 많아지면...

HTTP Interface가 하나 또는 두 개면 HttpServiceProxyFactory를 사용하여 프로시를 생성하는 것이 간단하지만, 그 수가 늘어나면 코드가 반복적으로 선언이 번거로워진다.

@Bean
UserService userService(HttpServiceProxyFactory proxyFactory) {
    return proxyFactory.createClient(UserService.class);
}

@Bean
ProductService productService(HttpServiceProxyFactory proxyFactory) {
    return proxyFactory.createClient(ProductService.class);
}

// More client beans

 

@ImportHttpServices 사용하기

@ImportHttpServices 어노테이션은 Spring Framework 7에 새롭게 추가되었다. @ImportHttpServices를 사용하면 그룹별로 HTTP 서비스를 적용할 수 있다.

@ImportHttpServices(group = "igooo", types = {UserService.class, ProductService.class, ...})
@ImportHttpServices(group = "aws", types = {RepositoryService.class, ...})
@Configuration
class HttpApiConfig {
}

 

또한 Spring Boot 4.0에서는 RestClient 및 WebClient auto configuration을 사용하여 각 그룹에 대한 설정을 적용할 수 있다.

spring:
  http:
    serviceclient:
      igooo:
        base-url: https://api.igooo.org/  
      aws: 
        base-url: https://api.aws.com/
    clients
      connect-timeout: 2s
      read-timeout: 2s

 

HttpServiceProxyRegistry

추가적으로 HTTP Interface는 동일하고 호출하는 주소만 다른 경우는 HttpServiceProxyRegistry를 사용하여 제어할 수 있다. 예를 들어 동일한 API를 환경별로 호출하는 경우는 아래와 같이 적용할 수 있다.

 

동일한 UserService Interface를 group 별로 지정한다.

@ImportHttpServices(group = "production", types = {UserSerice.class, ...})
@ImportHttpServices(group = "stage", types = {UserSerice.class, ...})
@ImportHttpServices(group = "test", types = {UserSerice.class, ...})
@Configuration
class HttpApiConfig {
}

 

UserSerice Interface를 개별로 주입할 수 없기 때문에 HttpServiceProxyRegistry를 사용하여 각 환경별로 Interface를 access한다.

class AccountService {
    private final HttpServiceProxyRegistry httpServiceProxyRegistry;
    
    AccountService(HttpServiceProxyRegistry httpServiceProxyRegistry) {
        this.httpServiceProxyRegistry = httpServiceProxyRegistry;
    }
    
    UserService userService(Enviroment env) {
        return this.httpServiceProxyRegistry.getClient(env.name, UserService.class);
    }
}

 

 

참고

https://spring.io/blog/2025/09/23/http-service-client-enhancements

 

 

728x90