Spring 시니어 프레임워크 심화 면접

Spring 시니어 (7년+) 프레임워크 5문항 조회수 89 · 2026-07-31 (금) 03:11:05
1 Spring Core - Bean Lifecycle
Hard

Q. Spring Bean의 전체 생명주기를 InitializingBean, DisposableBean 인터페이스와 @PostConstruct, @PreDestroy 어노테이션, 그리고 init-method/destroy-method 설정 방식을 포함하여 실행 순서대로 설명해주세요. 또한 각 방식의 장단점과 실무에서 어떤 기준으로 선택하는지 설명해주세요.

A. 모범답안

Spring Bean 생성 시 Constructor → @Autowired 의존성 주입 → @PostConstruct → InitializingBean.afterPropertiesSet() → init-method 순으로 실행되며, 소멸 시에는 @PreDestroy → DisposableBean.destroy() → destroy-method 순입니다. @PostConstruct/@PreDestroy는 JSR-250 표준으로 Spring에 종속되지 않아 가장 권장되며, InitializingBean/DisposableBean은 Spring 인터페이스에 강하게 결합되어 테스트가 어렵고, init-method/destroy-method는 XML 설정 시대의 레거시 방식입니다. 실무에서는 표준 준수와 테스트 용이성을 위해 @PostConstruct/@PreDestroy를 우선 사용하고, 외부 라이브러리 빈 설정 시에만 @Bean의 initMethod/destroyMethod 속성을 활용합니다.

핵심 포인트
  • • 생성: Constructor → 의존성 주입 → @PostConstruct → afterPropertiesSet() → init-method
  • • 소멸: @PreDestroy → destroy() → destroy-method
  • • @PostConstruct/@PreDestroy가 JSR-250 표준으로 가장 권장됨
  • • InitializingBean/DisposableBean은 Spring 강결합으로 테스트 어려움
  • • 외부 라이브러리 빈 설정 시 @Bean의 initMethod/destroyMethod 활용
Follow-up 질문

ApplicationContext를 shutdown할 때 Bean들이 정상적으로 destroy되지 않는 상황이 발생할 수 있는데, 이를 방지하기 위한 방법은 무엇인가요?

2 Spring MVC - Interceptor vs Filter
Medium

Q. Spring의 HandlerInterceptor와 Servlet Filter의 차이점을 실행 시점, 예외 처리, Spring 컨텍스트 접근성 측면에서 비교하고, 각각을 사용하기 적합한 실무 시나리오를 설명해주세요.

A. 모범답안

Filter는 Servlet Container 레벨에서 DispatcherServlet 이전에 동작하여 Spring 컨텍스트에 접근할 수 없고, 모든 요청에 대해 실행되며, 예외 발생 시 web.xml의 error-page로만 처리 가능합니다. HandlerInterceptor는 DispatcherServlet 이후 Controller 실행 전후에 동작하여 Spring Bean 주입이 가능하고, Handler 매핑 정보에 접근할 수 있으며, @ExceptionHandler나 @ControllerAdvice로 예외 처리가 가능합니다. Filter는 인코딩 설정, XSS 방어, 요청/응답 로깅 같은 저수준 처리에 적합하고, Interceptor는 인증/인가, 로깅, 트랜잭션 처리 같은 비즈니스 로직과 가까운 공통 관심사에 적합합니다.

핵심 포인트
  • • Filter는 Servlet Container 레벨, Interceptor는 Spring MVC 레벨에서 동작
  • • Filter는 Spring 컨텍스트 접근 불가, Interceptor는 Bean 주입 가능
  • • Interceptor는 Handler 정보 접근 가능하고 Spring 예외 처리 메커니즘 사용
  • • Filter는 인코딩/XSS 방어 등 저수준 처리에 적합
  • • Interceptor는 인증/인가 등 비즈니스 로직 관련 공통 관심사에 적합
Follow-up 질문

여러 개의 Interceptor가 등록되어 있을 때, 중간에 있는 Interceptor에서 예외가 발생하면 나머지 Interceptor들의 afterCompletion 메서드 실행 순서는 어떻게 되나요?

3 Spring Transaction - Propagation
Hard

Q. Spring의 트랜잭션 전파 속성 중 REQUIRES_NEW, NESTED, NOT_SUPPORTED의 동작 방식과 차이점을 설명하고, 각각이 실무에서 필요한 구체적인 시나리오를 예시와 함께 설명해주세요. 특히 NESTED의 Savepoint 메커니즘과 데이터베이스 지원 여부도 포함해주세요.

A. 모범답안

REQUIRES_NEW는 항상 새로운 물리적 트랜잭션을 시작하여 외부 트랜잭션과 완전히 독립적으로 커밋/롤백되며, 외부 트랜잭션이 롤백되어도 영향받지 않습니다. NESTED는 외부 트랜잭션 내에서 Savepoint를 생성하여 중첩 트랜잭션이 롤백되어도 외부는 영향받지 않지만, 외부가 롤백되면 함께 롤백되며 JDBC Savepoint를 지원하는 DB(Oracle, PostgreSQL 등)에서만 동작합니다. NOT_SUPPORTED는 기존 트랜잭션을 일시 중단하고 트랜잭션 없이 실행됩니다. REQUIRES_NEW는 알림 발송처럼 메인 로직 실패와 무관하게 기록해야 할 때, NESTED는 부분 실패 허용이 필요한 배치 처리에서, NOT_SUPPORTED는 대용량 조회 같이 트랜잭션이 불필요한 읽기 작업에 사용합니다.

핵심 포인트
  • • REQUIRES_NEW: 완전히 독립적인 새 물리 트랜잭션, 외부와 커밋/롤백 분리
  • • NESTED: Savepoint 기반 중첩, 내부 롤백은 외부에 영향 없으나 외부 롤백 시 함께 롤백
  • • NOT_SUPPORTED: 기존 트랜잭션 중단하고 트랜잭션 없이 실행
  • • NESTED는 JDBC Savepoint 지원 DB에서만 동작 (Oracle, PostgreSQL 등)
  • • REQUIRES_NEW는 감사 로그, NESTED는 배치 부분 실패, NOT_SUPPORTED는 대용량 조회에 활용
Follow-up 질문

REQUIRES_NEW를 사용할 때 외부 트랜잭션과 내부 트랜잭션이 동일한 데이터를 수정하려고 하면 어떤 문제가 발생할 수 있으며, 이를 어떻게 해결해야 하나요?

4 Spring Core - Event Publishing
Medium

Q. Spring의 ApplicationEvent와 @EventListener를 활용한 이벤트 기반 아키텍처 구현 시, 동기 이벤트와 비동기 이벤트의 차이점, 트랜잭션 경계 문제, 그리고 @TransactionalEventListener의 phase 옵션들(BEFORE_COMMIT, AFTER_COMMIT, AFTER_ROLLBACK, AFTER_COMPLETION)의 사용 시나리오를 설명해주세요.

A. 모범답안

기본 @EventListener는 동기로 동작하여 이벤트 발행자와 같은 스레드/트랜잭션에서 실행되므로 리스너 예외 시 발행자도 롤백되지만, @Async와 함께 사용하면 별도 스레드에서 비동기 실행되어 트랜잭션이 분리됩니다. @TransactionalEventListener는 트랜잭션 상태에 따라 실행 시점을 제어할 수 있으며, AFTER_COMMIT은 트랜잭션 커밋 성공 후 실행되어 외부 시스템 알림이나 캐시 무효화에 사용하고, BEFORE_COMMIT은 커밋 직전 검증에, AFTER_ROLLBACK은 롤백 후 보상 트랜잭션에, AFTER_COMPLETION은 커밋/롤백 여부와 무관하게 정리 작업에 사용합니다. 비동기 이벤트는 트랜잭션이 완료되기 전에 실행될 수 있어 데이터 정합성 문제가 발생할 수 있으므로, AFTER_COMMIT과 함께 사용하여 커밋 완료 후 비동기 처리하는 것이 안전합니다.

핵심 포인트
  • • @EventListener는 기본 동기, @Async 추가 시 비동기로 별도 스레드 실행
  • • @TransactionalEventListener로 트랜잭션 상태 기반 실행 시점 제어
  • • AFTER_COMMIT: 커밋 후 외부 알림/캐시 무효화, BEFORE_COMMIT: 커밋 전 검증
  • • AFTER_ROLLBACK: 롤백 후 보상 처리, AFTER_COMPLETION: 완료 후 정리
  • • 비동기 이벤트는 AFTER_COMMIT과 함께 사용하여 데이터 정합성 보장
Follow-up 질문

Spring Event를 사용할 때 이벤트 리스너에서 발생한 예외가 전파되지 않아 문제를 발견하기 어려운 경우가 있는데, 이를 모니터링하고 처리하기 위한 방법은 무엇인가요?

5 Spring Boot - Property Binding
Medium

Q. Spring Boot의 외부 설정 바인딩 메커니즘에서 @Value, @ConfigurationProperties, Environment의 차이점과 각각의 장단점을 설명하고, @ConfigurationProperties 사용 시 Relaxed Binding 규칙과 Validation 적용 방법을 설명해주세요.

A. 모범답안

@Value는 개별 프로퍼티를 SpEL로 주입하지만 타입 안정성과 메타데이터가 부족하고, @ConfigurationProperties는 prefix 기반으로 관련 설정을 객체로 그룹화하여 타입 안전성, IDE 자동완성, validation을 제공하며, Environment는 프로그래밍 방식으로 동적 접근이 가능합니다. @ConfigurationProperties는 Relaxed Binding을 지원하여 kebab-case(my-property), camelCase(myProperty), underscore(my_property), 대문자(MY_PROPERTY)를 모두 동일하게 매핑하며, @Validated와 JSR-303 어노테이션(@NotNull, @Min, @Max 등)으로 설정값 검증이 가능합니다. 실무에서는 단일 값은 @Value, 관련 설정 그룹은 @ConfigurationProperties, 동적 접근은 Environment를 사용하며, 특히 @ConfigurationProperties는 불변 객체로 만들어 @ConstructorBinding을 활용하는 것이 권장됩니다.

핵심 포인트
  • • @Value: 개별 값 주입, SpEL 지원하지만 타입 안정성 부족
  • • @ConfigurationProperties: 설정 그룹화, 타입 안전성, IDE 지원, Validation 가능
  • • Relaxed Binding으로 kebab-case, camelCase, underscore, 대문자 모두 매핑
  • • @Validated와 JSR-303으로 설정값 검증 (@NotNull, @Min, @Max 등)
  • • @ConstructorBinding으로 불변 객체 생성 권장
Follow-up 질문

application.yml과 application.properties에서 List나 Map 타입의 복잡한 설정을 바인딩할 때 각 포맷의 문법 차이와 주의사항은 무엇인가요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!