Spring 미드레벨 기술면접
새 면접Q. Spring에서 생성자 주입, 필드 주입, Setter 주입의 차이점을 설명하고, 생성자 주입이 권장되는 이유를 불변성, 테스트 용이성, 순환 참조 관점에서 설명해주세요. 또한 생성자 주입 시 순환 참조가 발생하면 어떤 에러가 발생하고 어떻게 해결할 수 있는지 설명해주세요.
생성자 주입은 객체 생성 시점에 의존성을 주입하여 불변성을 보장하고, 필드를 final로 선언할 수 있어 NPE를 방지합니다. 필드 주입과 달리 Spring 컨테이너 없이도 순수 자바로 테스트가 가능하며, 생성자 주입 시 순환 참조는 애플리케이션 시작 시점에 BeanCurrentlyInCreationException으로 감지됩니다. 순환 참조 해결 방법으로는 @Lazy 애노테이션 사용, 설계 개선을 통한 의존성 분리, 또는 Setter 주입으로 변경하는 방법이 있지만 근본적으로는 설계를 재검토하는 것이 바람직합니다.
- • 생성자 주입은 final 필드 선언으로 불변성 보장
- • Spring 컨테이너 없이 POJO 테스트 가능
- • 순환 참조를 애플리케이션 시작 시점에 조기 감지
- • @Lazy나 설계 개선으로 순환 참조 해결
Lombok의 @RequiredArgsConstructor를 사용할 때의 장점과 주의사항은 무엇인가요?
Q. JPA에서 변경 감지(Dirty Checking)의 동작 원리를 설명하고, 영속성 컨텍스트의 스냅샷 비교 메커니즘을 설명해주세요. 또한 대량의 엔티티를 수정할 때 변경 감지보다 벌크 연산(@Modifying)을 사용하는 것이 더 효율적인 이유와, 벌크 연산 사용 시 주의해야 할 영속성 컨텍스트 동기화 문제를 설명해주세요.
변경 감지는 영속성 컨텍스트가 엔티티 조회 시점의 스냅샷을 보관하고, 트랜잭션 커밋 시 flush() 과정에서 현재 엔티티와 스냅샷을 비교하여 변경된 필드에 대해 UPDATE 쿼리를 자동 생성합니다. 대량 수정 시 벌크 연산은 한 번의 쿼리로 DB를 직접 수정하여 효율적이지만, 영속성 컨텍스트를 거치지 않아 1차 캐시와 DB 간 불일치가 발생합니다. 따라서 벌크 연산 후에는 em.clear()로 영속성 컨텍스트를 초기화하거나, clearAutomatically=true 옵션을 사용해야 합니다.
- • 스냅샷 비교를 통한 자동 UPDATE 쿼리 생성
- • 벌크 연산은 영속성 컨텍스트를 우회하여 DB 직접 수정
- • 벌크 연산 후 영속성 컨텍스트 초기화 필요
- • 대량 수정 시 성능 차이가 크게 발생
동적 업데이트(@DynamicUpdate)를 사용하는 것이 항상 성능상 유리한가요?
Q. Spring의 @Transactional에서 readOnly=true 옵션의 동작 원리와 성능 최적화 효과를 Hibernate의 flush 모드, DB 커넥션, 스냅샷 생성 관점에서 설명해주세요. 또한 readOnly 트랜잭션 내에서 실수로 엔티티를 수정하면 어떤 일이 발생하는지 설명해주세요.
readOnly=true 옵션은 Hibernate의 flush 모드를 MANUAL로 설정하여 변경 감지를 위한 스냅샷 생성을 생략하고, 트랜잭션 커밋 시 flush를 수행하지 않아 성능이 향상됩니다. 또한 DB 드라이버에 읽기 전용 힌트를 전달하여 DB가 내부적으로 최적화를 수행할 수 있습니다. readOnly 트랜잭션에서 엔티티를 수정하면 스냅샷이 없어 변경 감지가 작동하지 않아 DB에 반영되지 않지만, 명시적으로 flush()를 호출하면 TransactionReadOnlyException이 발생할 수 있습니다.
- • flush 모드 MANUAL로 변경 감지 비활성화
- • 스냅샷 생성 생략으로 메모리 절약
- • DB 레벨의 읽기 최적화 활성화
- • readOnly 트랜잭션에서 수정은 반영되지 않음
읽기 전용 트랜잭션에서도 격리 수준(Isolation Level)을 설정할 수 있나요? 어떤 경우에 필요한가요?
Q. Spring Boot의 Auto Configuration 동작 원리를 @EnableAutoConfiguration, spring.factories, @Conditional 애노테이션 관점에서 설명하고, 특정 Auto Configuration을 비활성화하거나 커스터마이징하는 방법을 설명해주세요. 또한 자신만의 Auto Configuration을 만들 때 고려해야 할 사항을 설명해주세요.
@EnableAutoConfiguration은 spring.factories 파일에 등록된 설정 클래스들을 읽어와서 @Conditional 계열 애노테이션으로 조건을 평가하여 Bean을 자동 등록합니다. 특정 Auto Configuration 비활성화는 @SpringBootApplication(exclude) 또는 spring.autoconfigure.exclude 프로퍼티를 사용하며, 커스터마이징은 동일한 타입의 Bean을 직접 정의하면 @ConditionalOnMissingBean에 의해 자동 설정이 적용되지 않습니다. 커스텀 Auto Configuration 작성 시에는 @ConditionalOnClass로 관련 라이브러리 존재 여부를 확인하고, @AutoConfigureAfter/@AutoConfigureBefore로 순서를 제어하며, 프로퍼티 기반 설정을 위해 @ConfigurationProperties를 활용해야 합니다.
- • spring.factories에서 설정 클래스 목록 로드
- • @Conditional 애노테이션으로 조건부 Bean 등록
- • exclude 옵션이나 직접 Bean 정의로 비활성화
- • 커스텀 Auto Configuration은 조건 평가와 순서 제어 필요
@ConditionalOnBean과 @ConditionalOnMissingBean의 평가 시점과 주의사항은 무엇인가요?
Q. Spring에서 @ExceptionHandler, @ControllerAdvice, ResponseEntityExceptionHandler의 역할과 차이점을 설명하고, RESTful API에서 일관된 에러 응답 구조를 설계할 때 고려해야 할 사항들을 설명해주세요. 또한 비즈니스 예외와 시스템 예외를 어떻게 구분하여 처리해야 하는지 설명해주세요.
@ExceptionHandler는 특정 컨트롤러 내에서 예외를 처리하고, @ControllerAdvice는 전역적으로 여러 컨트롤러의 예외를 한 곳에서 처리합니다. ResponseEntityExceptionHandler는 Spring MVC의 표준 예외들에 대한 기본 처리를 제공하며 이를 상속하여 커스터마이징할 수 있습니다. 일관된 에러 응답을 위해서는 에러 코드, 메시지, 타임스탬프, 상세 정보를 포함한 표준 응답 구조를 정의해야 하며, 비즈니스 예외는 명시적인 커스텀 예외로 정의하여 클라이언트에게 상세 정보를 제공하고, 시스템 예외는 내부 정보를 숨기고 일반적인 에러 메시지만 반환해야 합니다.
- • @ControllerAdvice로 전역 예외 처리 중앙화
- • 표준 에러 응답 구조 정의 (코드, 메시지, 타임스탬프)
- • 비즈니스 예외는 상세 정보 제공, 시스템 예외는 정보 은닉
- • HTTP 상태 코드를 의미에 맞게 사용
Filter에서 발생한 예외는 @ControllerAdvice에서 처리할 수 있나요? 처리할 수 없다면 어떻게 해야 하나요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!