--- kind: CASE slug: validator-declared-and-never-injected title: 같은 자동 설정 안에서 검증기 하나만 감싸이지 않아 트랜잭션 조건이 검사되지 않는다 topic: runtime-reachability-and-composition project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:validator-declared-and-never-injected evidenceCapturedOn: 2026-09-01 body: case-validator-declared-and-never-injected.body.md assets: - key: validator-declared-and-never-injected file: ../../../final/evidence/rendered/validator-declared-and-never-injected.svg evidence: - ../../../final/evidence/raw/validator-declared-and-never-injected.txt source: - 원본 분석 절은 analysis/messaging/messaging-spring-boot-starter.md#L148 이다. --- # 같은 자동 설정 안에서 검증기 하나만 감싸이지 않아 트랜잭션 조건이 검사되지 않는다 한 자동 설정이 검증기 둘을 만든다. 하나는 시작 검증 도우미로 감싸여 컨텍스트 구성 중에 돌고, 다른 하나는 빈으로 발행만 된다. 그 도우미의 자바독이 서술한 이전 결함이 정확히 그 형태다. ## 관계 - **시작 검증기가 유일한 소비자인 설정 키 넷이 아무것도 게이트하지 않는다** 같은 통독에서 나온 짝이다. - **검증기는 발행이 아니라 주입이 강제다** 이 사례에서 뽑은 규칙이다. - **능력 상수가 프로파일 조건보다 오래 살아서 중복 제거 없는 목적지가 가드를 통과한다** 같은 어댑터 계열의 짝이 되는 사례다. ## 문제 시작 검증 도우미가 이 가족에서 이미 한 번 고쳐진 결함을 자바독에 기록한다. 브로커 두 종과 보안 검증기가 전부 빈이었는데 아무 데도 주입되지 않았다는 것이다. 컨텍스트가 브로커마다 검증기를 발행하고 아무것도 검증하지 않았다는 것이다. 그 수정이 적용된 뒤의 상태를 확인했다. ## 결론 같은 자동 설정 안에서 하나가 빠져 있다. 브로커 프로파일 검증기는 도우미로 감싸여 초기화 콜백에서 돈다. 같은 파일의 트랜잭션 프로파일 검증기는 빈으로 발행만 된다. 대응하는 도우미 선언이 없다. 다른 브로커의 자동 설정은 검증기가 하나뿐이고 그것을 감싼다. 그러므로 이 가족에서 감싸이지 않은 검증기는 이 하나다. 그 검증기가 무엇을 막는지는 자기 자바독이 적는다. 트랜잭션 식별자 접두와 멱등 생산자와 모든 복제 확인과 수동 오프셋 커밋을 요구하고, 마지막 규칙이 핵심이다. 부수효과가 데이터베이스에 사는 목적지가 브로커 트랜잭션을 함께 선언하면, 팀이 트랜잭션이라는 낱말을 두 번 읽고 전체 경로가 원자적이라고 결론짓는다는 것이다. 두 절반은 여전히 갈라질 수 있다. 그 검증이 지금 돌지 않는다. 그리고 같은 어댑터의 능력 선언은 브로커 트랜잭션을 무조건 참으로 답한다. 두 겹이 함께 비어 있다. 여기서 리프 경계를 넘어야만 보이는 것이 하나 있다. 검증기는 어댑터 리프가 소유하고, 그것을 시작 시 부르는 배선은 스타터가 소유한다. 어느 쪽 문서도 혼자서는 이 검증이 실행되지 않는다는 것을 말할 수 없다. ## 검증 환경 Spring Boot : 4.0.8 확인 방식 : 자동 설정의 빈 선언 대조와 형제 자동 설정 비교 소스 수정 : x ## 재현 조건 원문은 document-detail 의 analysis/messaging/messaging-spring-boot-starter.md 에 있다. 1. 시작 검증 도우미의 자바독을 읽는다. 2. 브로커 자동 설정의 빈 선언을 순서대로 읽는다. 3. 각 검증기에 대응하는 도우미 선언이 있는지 확인한다. 4. 다른 브로커의 자동 설정과 비교한다. 5. 감싸이지 않은 검증기가 무엇을 요구하는지 읽는다. ## 본문 `KafkaProfileValidator` 는 `StartupProfileValidation` 으로 감싸여 `afterPropertiesSet` 에서 돌고, 같은 파일의 `KafkaTransactionProfileValidator` 는 빈으로 발행만 된다. Rabbit 쪽은 하나뿐인 검증기를 감싼다. ## KafkaProfileValidator 참조 위치 :::evidence key="validator-declared-and-never-injected" alt="코드베이스에서 KafkaProfileValidator 를 검색한 출력 3줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="KafkaProfileValidator 코드베이스 검색 — 3줄 · exit 0" zoom="true" ::: ## 검사되지 않는 네 조건 트랜잭션 식별자 접두·멱등 생산자·`acks=all`·수동 커밋 요구가 시작 시 검사되지 않고, 어댑터는 `brokerTransaction=true` 를 무조건 답한다. ## 어느 문서도 혼자서는 이 사실을 말할 수 없다 검증기의 절반은 `messaging-kafka` 가, 배선의 절반은 스타터가 소유한다. ## 확인하지 못한 것 조건을 어긴 프로파일로 컨텍스트를 세워 검증이 돌지 않는 것을 재현하지 않았다.