--- title: "Hexagonal Architecture with Java and Spring — Reflectoring (Tom Hombergs)" source_type: company-tech-blog url: https://reflectoring.io/spring-hexagonal/ archive_url: status: raw confidence: medium tags: [ca-transaction-boundary, hexagonal, at-transactional, application-service] related_branches: [feature-application-port-usecase-contract, feature-transaction-concurrency-contract] related_projects: [ca-skeleton-operational-contract] created: 2026-05-22 last_reviewed: 2026-05-27 --- # Hexagonal Architecture with Java and Spring — Tom Hombergs / Reflectoring > Layer: `raw/company-tech-blogs/` — 외부 엔지니어 블로그의 **원문 발췌·출처 기록**. Tom Hombergs (저서 *Get Your Hands Dirty on Clean Architecture* 저자) 의 reflectoring.io 레퍼런스 글로, 헥사고날 사실상 표준 패턴에서 `@Transactional` 위치를 보여주는 baseline 사례. > 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. ## Parent / 활용 branch (필수) | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-application-port-usecase-contract]] | ca-tmpl 이 의식적으로 거부한 baseline 패턴 (`@Transactional` 을 use case 구현체에 직접 부착) 의 사례 근거 | | [[raw/branch-notes/feature-transaction-concurrency-contract]] | Topic 2 — Transaction Boundary 대안 비교에서 "대안 1: @Transactional direct" 의 reference 구현체 | | [[raw/project-notes/ca-skeleton-operational-contract]] | §14. Transaction / Concurrency Contract — ca-tmpl 의 TransactionPort 결정에 대한 비교군 baseline | ## 컨텍스트 / 왜 저장했는지 ca-tmpl 결정의 비교군: **헥사고날 아키텍처 사실상 표준 reference 에서 `@Transactional` 을 application service(use case) 에 직접 부착하는 사례.** 즉 ca-tmpl 이 의식적으로 거부한 baseline 패턴을 옹호하는 참조. ## 출처 / Source - 원본 URL: https://reflectoring.io/spring-hexagonal/ - 아카이브 URL: (미수집) - 저자 / 조직: Tom Hombergs (저서 *Get Your Hands Dirty on Clean Architecture* 저자) / reflectoring.io - 발행일: continuously updated reference article - 마지막 확인일: 2026-05-27 ## 핵심 인용 / Key quotes (verbatim) > [§Building a Use Case and Output Ports] "```@RequiredArgsConstructor @Component @Transactional public class SendMoneyService implements SendMoneyUseCase {```" > [§Input and Output Ports] "An input port is a simple interface that can be called by outward components and that is implemented by a use case." > [§Input and Output Ports] "An output port is again a simple interface that can be called by our use cases if they need something from the outside." > [§Input and Output Ports] "A use case in this sense is a class that handles everything around, well, a certain use case." > [§Building a Web Adapter] "If you're familiar with Spring MVC, you'll find that this is a pretty boring web controller." ## Claims Extracted / 추출된 주장 | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | HEX-REFL-C1 | reflectoring 레퍼런스 예제에서 `SendMoneyService` (use case 구현체) 가 `@Component` + `@Transactional` 을 직접 부착 | [§Building a Use Case and Output Ports] "```@RequiredArgsConstructor @Component @Transactional public class SendMoneyService implements SendMoneyUseCase {```" | `engineering-blog` | Spring + 헥사고날 baseline 패턴 | 이 배치가 모든 헥사고날 구현의 모범이라는 뜻은 아님 — 저자도 명시적 정당화는 책으로 미룸 | | HEX-REFL-C2 | input port 는 외부 컴포넌트가 호출하는 단순 인터페이스이고 use case 가 구현한다 | [§Input and Output Ports] "An input port is a simple interface that can be called by outward components and that is implemented by a use case." | `engineering-blog` | 헥사고날의 port 정의 (저자 관점) | port 의 granularity (큰 port 1개 vs use case 당 port 1개) 는 본 인용 범위 밖 | | HEX-REFL-C3 | output port 는 use case 가 외부에 무언가 필요할 때 호출하는 단순 인터페이스 | [§Input and Output Ports] "An output port is again a simple interface that can be called by our use cases if they need something from the outside." | `engineering-blog` | 헥사고날의 driven-adapter 통신 방향 정의 | output port 가 트랜잭션 제어를 담당해야 한다는 뜻은 아님 — 본 글은 그 결정을 다루지 않음 | | HEX-REFL-C4 | use case 는 "특정 use case 주변의 모든 것" 을 처리하는 클래스이다 | [§Input and Output Ports] "A use case in this sense is a class that handles everything around, well, a certain use case." | `engineering-blog` | 헥사고날 use case 의 책임 정의 | "모든 것" 의 정확한 경계 (트랜잭션, 인증, 검증 포함 여부) 는 본 인용에 명시 없음 | | HEX-REFL-C5 | 본 글은 transaction boundary 정책 / `@Transactional` 부착 위치에 대한 명시적 권고 또는 정당화를 **하지 않는다** (예제로만 보여줌) | (부재 자체가 claim — WebFetch 재확인: "No explicit recommendation provided"; 본 인용 내에 transaction boundary 권고 문장 없음) | `needs-confirmation` | 본 글의 표현 범위 | 저자가 다른 매체 (책) 에서 다룬 정당화는 본 인용으로 증명 안 됨 | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것**: - `HEX-REFL-C1`: reflectoring 의 canonical 예제 코드 그대로의 `@Transactional` 위치 (use case 구현체 클래스) - `HEX-REFL-C2` ~ `C4`: 저자의 port 와 use case 정의 (Hombergs 관점) - `HEX-REFL-C5`: 본 글이 transaction boundary 결정의 정당화를 직접 제공하지 않는다는 사실 - **이 자료가 증명하지 않는 것**: - 이 패턴이 헥사고날 커뮤니티의 "공식 best practice" 라는 주장 (`company-tech-blog` 수준이 아니라 `engineering-blog` 수준 — 개인 블로그) - 이 패턴이 prod 환경에서 검증되었다는 주장 (저자의 책/블로그 reference 예제일 뿐) - "framework-free 원칙 위반" 이라는 비판 — 본 글이 직접 그 표현을 쓰지 않음 - **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: - ca-tmpl 의 TransactionPort 가 reflectoring 패턴 대비 갖는 dependency rule 차이 (Spring annotation import 유무) 의 실제 측정 - 저자의 책 *Get Your Hands Dirty on Clean Architecture* 에서 동일 결정의 정당화 본문 확인 ## 메모 / Notes (내 프로젝트 해석) > 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. - 이 패턴이 한국·해외 헥사고날 튜토리얼의 90% 이상에서 그대로 반복됨. ca-tmpl 의 결정은 이 디폴트에 대한 의식적 일탈로 봐야 함. - 적용 시나리오: 빠른 프로토타이핑, 팀이 Spring 이외 stack 으로 옮길 계획이 없는 경우. - 장점: - 코드 적음. 진입 장벽 최저. - 헥사고날 커뮤니티 표준이라 코드 리뷰/온보딩 용이. - 단점: - application 레이어가 `org.springframework.transaction.annotation.Transactional` 을 import → 책에서 강조하는 "domain-application 은 framework-free" 원칙과 실제 코드가 어긋남. (저자도 명시적 정당화 없음 — `HEX-REFL-C5` 참조.) - 트랜잭션 boundary 테스트가 Spring context 를 요구. - ca-tmpl(TransactionPort) 와의 차이: ca-tmpl 은 위 모순을 닫기 위해 `TransactionPort` + `TransactionalUseCaseRunner` 로 한 단계 더 abstraction 을 둠. Reflectoring 패턴은 그 모순을 실용주의로 수용. - testability 영향: 낮음. - code 복잡도 영향: 낮음 (하지만 dependency-rule cost 는 숨겨져 있음). ## Related / 관련 - 같은 주제 다른 raw: - [[raw/company-tech-blogs/transaction-port-clean-ddd-spring-medium]] (TransactionPort 도입 사례) - [[raw/company-tech-blogs/transaction-port-vassilis-soum-github-readme]] (TransactionInterceptor 확장) - [[raw/company-tech-blogs/woowahan-hexagonal-multimodule]] (multi-module 보완) - 인용하는 branch: - [[raw/branch-notes/feature-application-port-usecase-contract]] - [[raw/branch-notes/feature-transaction-concurrency-contract]] - 인용하는 project: - [[raw/project-notes/ca-skeleton-operational-contract]] (§14, §5) - 인용한 wiki 요약: (미작성) - 대안 그룹: **Topic 2 — Transaction Boundary** (대안 5종: TransactionPort / @Transactional direct / TransactionTemplate / Functional monad / Custom AOP) - 본 source 의 위치: 대안 1: @Transactional direct (Hexagonal 변형)