인프런 커뮤니티 질문&답변

퉁튱님의 프로필 이미지
퉁튱

작성한 질문수

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

Spring Cloud Gateway - Logging Filter

Filter 람다식 관련 질문드립니다.

작성

·

587

0

안녕하세요!

Custim Filter 강의 중 아래 코드 부분에서 GatewayFilter의 생성자가 exchange와 chain이기 때문에 return (exchange, chain) -> { .. 이 되는 것 까지는 이해를 하였습니다.
그런데 이 때 exchange와 chain 변수가 어디에서 정의되어서 여기서 사용되는 건지 잘 모르겠습니다 ㅠㅠ

  return (exchange, chain) -> {
// GatewayFilter의 생성자
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

답변 2

3

Dowon Lee님의 프로필 이미지
Dowon Lee
지식공유자

안녕하세요, 이도원입니다.

말씀하신 내용처럼 CustomFilger를 잘 사용하기 위해서 Java의 Lambda식 함수형 프로그래밍을 같이 이해하시는게 필요합니다. 먼저 Lambda는 자바의 익명함수를 사용하는 방법이라고 생각하시면 되는데, 위 예제처럼 GatewayFilter 인터페이스에 선언된 filter라는 메소드는 추상 메소드로써(메소드 Body가 없는) 아래와 같이 filter(ServerWebExchange exchange, GatewayFilterChain chain)이라는 2개의 파라미터를 갖도록 선언되어 있습니다. 선언만 되어 있지 실제로 어떠한 내용으로 처리될지는 GatewayFilter 인터페이스에서는 결정되지 않았습니다. CustomFilter의 apply 함수로 이동해 보면, 해당 appy 메소드의 반환 값으로 GatewayFilter 형태로 반환해야 하는데, GatewayFilter는 인터페이스이기 때문에 어딘가에 구현체가 있어야 반환될 수 있습니다. 이 작업을 apply 메소드에서 처리하고 있는데, GatewayFilter의 filter 메소드에 대한 Body 구현을 직접처리하고 있습니다. 아래 메소드에서의 exchange와 chain은 GatewayFilter의 filter 메소드의 인자값으로 전달될 내용이며, GatewayFilter의 filter 메소드에 선언된 유형과 순서가 맞다면 어떤 이름이어도 상관은 없습니다.

@Override
public GatewayFilter apply(Config config) {
    // Custom Pre Filter
    return (exchange, chain) -> {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        log.info("Custom PRE filter: request id -> {}", request.getId());

        // Custom Post Filter
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            log.info("Custom POST filter: response code -> {}", response.getStatusCode());
        }));
    };
}
public interface GatewayFilter extends ShortcutConfigurable {
    String NAME_KEY = "name";
    String VALUE_KEY = "value";

    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

정리하면, CustomFilter의 apply 메소드에서 사용하고 있는 exchange, chain 값은 어딘가에서 선언된 것이 아니라, 이 코드를 사용하는 시점에 임의로 선언해서 GatewayFilter의 filter 메소드에 전달되는 객체입니다. 해당 객체를 이용하여 filter메소드이 body를 구현하였고, 마지막에 chain.filter 를 이용하여 반환하고 있는 구조입니다. 글로 설명하려니 조금 어렵긴 한데, 어느정도 이해가 되셨기를 바랍니다. 추가 질문이 있으시면 언제든지 글 남겨주세요.

0

퉁튱님의 프로필 이미지
퉁튱
질문자

감사합니다!!

퉁튱님의 프로필 이미지
퉁튱

작성한 질문수

질문하기