# 앞 필터는 자동설정이 조립한다
1:dev.caskeleton.adapter.inbound.web.mvc.autoconfigure.WebMvcPlatformAutoConfiguration
47:@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
  public WebMvcRequestIdFilter webMvcRequestIdFilter(WebMvcPlatformSettings properties) {
    return new WebMvcRequestIdFilter(
        properties.trustInboundRequestId(),
        org.springframework.core.Ordered.HIGHEST_PRECEDENCE + 10);
  }

# 그 설정값의 기본은 거짓이다
    // Defaults to false: a caller that can choose its own request id can make two exchanges share
    // one identity, which is how a support investigation reads somebody else's request.
    trustInboundRequestId = trustInboundRequestId != null && trustInboundRequestId;
#   무인자 생성자를 부르는 곳: WebMvcRequestIdFilterTest.java:21:    new WebMvcRequestIdFilter().doFilter(request, response, new MockFilterChain()); WebMvcRequestIdFilterTest.java:56:    new WebMvcRequestIdFilter() WebMvcRequestIdFilterTest.java:63:    new WebMvcRequestIdFilter() 

# 두 필터가 같은 헤더 이름을 따로 선언한다
42:  public static final String REQUEST_ID_HEADER = "X-Request-Id";
45:  public static final String TRACEPARENT_HEADER = "traceparent";
40:  private static final String HEADER_REQUEST_ID = "X-Request-Id";
42:  private static final String HEADER_TRACEPARENT = "traceparent";

# 앞 필터: 순서를 선언하고 자기 값을 속성과 응답 헤더에 쓴다
147:        org.springframework.core.Ordered.HIGHEST_PRECEDENCE + 10);
81:      request.setAttribute(REQUEST_ID_ATTRIBUTE, requestId);
85:      response.setHeader(REQUEST_ID_HEADER, requestId.value());

# 뒤 필터: 스캔되고, 순서 선언이 없고, 정화한 클라이언트 값을 같은 헤더와 MDC 에 쓴다
35:@Component
  순서 선언(@Order/Ordered/getOrder) 매치: 0
43:  private static final int MAX_ID_LENGTH = 200;
92:    String clean = HeaderSanitizer.sanitize(inbound, MAX_ID_LENGTH);
    String requestId = resolveOrGenerate(req.getHeader(HEADER_REQUEST_ID));
    String correlationId = resolveOrGenerate(req.getHeader(HEADER_CORRELATION_ID));
    res.setHeader(HEADER_REQUEST_ID, requestId);
    MDC.put(MdcKeys.REQUEST_ID, requestId);
    res.setHeader(HEADER_TRACEPARENT, traceParent.toHeader());

# 스캔 제외 정규식에 이 패키지가 있는가
package dev.caskeleton.adapter.inbound.web.filter;
  제외 정규식의 web 항목: inbound\\.web\\.fileserver\\.admin inbound\\.web\\.mvc\\.error inbound\\.web\\.mvc\\.budget inbound\\.web\\.mvc\\.operation inbound\\.web\\.webflux\\.error inbound\\.web\\.webflux\\.operation 
  그중 web.filter 매치: 0

# 앞 필터가 속성에 넣은 값을 읽는 main 코드
136:  public static Optional<WebRequestId> requestId(HttpServletRequest request) {
  그 접근자와 속성 상수를 읽는 main 참조: 0

# 정화가 버리는 범위
    for (int i = 0; i < raw.length() && sb.length() < maxLength; i++) {
      char c = raw.charAt(i);
      if (c >= 0x20) {
        sb.append(c);
      }
    }
