반응형 Spring/Common11 [Spring] 스프링 메세지와 국제화 정리 1. 도입부 (Introduction)웹 애플리케이션을 개발하고 운영하다 보면, 화면에 노출되는 수많은 텍스트(라벨, 메시지, 오류 문구 등)를 관리해야 하는 시점이 찾아온다. 처음에는 HTML 파일 곳곳에 직접 "상품명", "가격"과 같은 단어들을 직접 타이핑하곤 하지만, 요구사항이 변경되어 "상품명"을 "아이템 이름"으로 한 번에 변경해야 한다면 어떨까? 수십, 수백 개의 HTML 템플릿을 일일이 열어서 수정해야 하는 비효율적인 상황, 즉 '유지보수의 재앙'을 마주하게 된다.이러한 문제를 깔끔하게 해결하기 위해 스프링이 지원하는 무기가 바로 메시지(Message) 기능과 국제화(Internationalization, i18n) 기능이다. 공통 텍스트를 파일 하나로 격리하여 중앙 집중식으로 관리하고, .. 2026. 5. 24. [Spring] 사용자 도메인 정책을 테스트로 '고정(Locking)'하는 실패 중심 테스트 설계법 1. 도입부 (Introduction)백엔드 프로젝트를 리팩토링하거나 새로운 기능을 추가할 때, 가장 빈번하게 발생하는 참사는 "잘 돌아가던 기존의 도메인 차단 규칙이나 인가 장벽이 소리 소문 없이 해제되는 것"이다. 예를 들어, 팔로우 테이블의 쿼리 구조를 성능 튜닝하기 위해 수정했더니 "자기 자신 팔로우 금지" 정책이나 "차단한 유저 팔로우 금지"와 같은 네거티브 수문장 로직이 누락되어 버리는 현상이다.동작 자체는 에러 없이 200 OK로 완료되기 때문에, 비즈니스 무결성이 붕괴되었다는 사실은 테스트 코드에서 꼼꼼히 잡아내지 않으면 릴리즈 이후 실제 불량 유저들의 부정 거래나 어드민 탈취 같은 치명적인 보안 사고가 터진 뒤에야 감지된다.사용자 도메인처럼 규제와 제한이 빼곡한 시스템에서는 "무엇이 허용.. 2026. 5. 23. [Spring] 차단을 활용한 트랙잭션 경계 설계와 웹훅 결합시 마주하는 장애 분석 1. 도입부 (Introduction)사용자가 커뮤니티나 SNS 플랫폼에서 다른 사용자를 "차단(Block)"하는 행위는 단순히 관계형 데이터베이스에 차단 이력(Row)을 한 줄 적재하는 가벼운 이벤트가 아니다. 도메인 관점에서 차단은 "두 사용자 사이에 존재하는 모든 상호작용 규칙과 권한 구조를 즉시 파괴하고 재구성하는 중대한 아키텍처적 사건"이다.많은 주니어 개발자들이 저지르는 실수는 차단 테이블(MemberBlock)에 단순히 데이터를 저장(INSERT)하는 기능만 만들고 비즈니스를 끝내는 것이다. 그러나 차단 이력만 적재하고 기존에 형성되어 있던 양방향 팔로우 관계를 물리적으로 정리하지 않으면, DB 쿼리에 미세한 필터 구멍이 생기는 순간 차단당한 자가 blocker의 비공개 피드를 훔쳐보거나 팔.. 2026. 5. 22. [Spring] 소셜 관계 도메인 : '제약 기반 관계 정책' 설계 1. 도입부 (Introduction)현대 애플리케이션에서 사용자 간의 '관계(Relationship)'를 정의하는 팔로우, 친구 추가, 구독 등의 기능은 매우 흔하게 설계된다. 대다수의 백엔드 개발은 초기 단계에서 단순히 두 사용자 간의 매핑 테이블(예: Follow 테이블)을 생성하고, 행(Row)을 추가하거나 삭제하는 수준의 단순 CRUD API로 접근한다.하지만 실제 상용 서비스 레벨의 아키텍처에서는 강력한 규제 조건인 '차단(Block)' 정책이 개입하는 순간 이 간단해 보이던 도메인의 복잡도가 급격하게 치솟는다. 쓰기(Write) 시점에 차단 관계를 정상적으로 거르지 못하거나, 데이터베이스 저장에는 성공했으나 정작 목록 조회(Read) 시 차단된 상대방의 프로필이나 활동이 여전히 노출되는 경우.. 2026. 5. 21. [Spring] 엔티티를 단순 테이블 매핑이 아닌 '정책 상태 머신'으로 설계해야 하는 이유 1. 도입부 (Introduction)전통적인 데이터베이스 중심 아키텍처에서 엔티티(Entity)는 단순히 테이블의 컬럼들을 자바 객체로 1:1 매핑해 둔 빈 껍데기(Anemic Domain Model)로 취급받기 일쑤다. 서비스 레이어에서 엔티티의 내장 Getter와 Setter를 무분별하게 호출하며 자바 필드 값을 직접 덮어쓰는 방식은 도메인 제어권을 통째로 상실하게 만든다. 비즈니스 정책이 복잡해질수록 온보딩 확정, 가입 차단, 불량 유저 제재 등과 같은 엄격한 상태 전환 규칙들이 사방으로 흩어져 유지보수 불가능한 스파게티 코드가 되기 때문이다.이러한 문제를 해결하기 위해서는 User 엔티티를 단순한 CRUD의 데이터 뭉치가 아니라, 오직 정해진 비즈니스 조건과 제약사항에 의해서만 다음 단계로 이행.. 2026. 5. 21. [Spring] 빈 생명주기 콜백: 애플리케이션의 시작과 종료 관리 애플리케이션을 만들다 보면 DB 커넥션 풀을 미리 연결하거나 네트워크 소켓을 열어두는 등, 객체의 시작과 종료 시점에 세밀한 제어가 필요한 순간이 온다. 오늘은 스프링 빈 생명주기 콜백의 "현대적 표준"을 중심으로, 단순히 쓰는 법을 넘어 내부 동작 원리까지 깊게 파헤쳐 보려고 한다. 1. 생명주기 콜백이 꼭 필요한 이유자바의 일반적인 객체와 스프링 빈의 가장 큰 차이는 '의존관계 주입'이라는 단계의 유무다.의존성 주입의 선행: 빈은 인스턴스화(생성)된 직후에는 필드에 아무것도 들어있지 않다. 만약 생성자에서 주입받은 URL을 사용해 바로 접속을 시도하면 NullPointerException을 만나게 된다.준비 완료 시점의 통지: 스프링은 모든 의존관계 주입이 끝나야 비로소 객체가 "일할 준비가 되었다".. 2026. 5. 10. 이전 1 2 다음 반응형