1) ThreadLocal
ThreadLocal을 사용하면 좋은 경우
- Bean처럼 여러 스레드에서 공유되는 구조가 아니라
- 한 스레드 내부에서만 전역적으로 접근이 필요할 때
ThreadLocal 사용 시 주의점
- 스레드 재사용(특히 스레드풀) 환경에서 값이 다음 작업에 남을 수 있음
- 사용 완료 후 반드시 제거(remove) 해야 함
2) 템플릿 메서드 패턴(Template Method)
개념
- 핵심 기능과 부가기능 분리
- 변경이 필요한 핵심 기능만 교체하도록 설계
구조(요지)
Abstract클래스- 핵심:
call()같은 추상 메서드에서 구현 execute()가 부가기능 +call()을 함께 수행
주의점(한계)
- 상속 기반
- 부가기능까지 변경되면 부모 수정 필요 → OCP 위배 가능
3) 전략 패턴(Strategy)
개념
- 템플릿 메서드 패턴의 상속 문제 보완(합성 사용)
구조(요지)
- 부가기능을 담당하는 Context(또는 Template) 클래스 존재
- 핵심 기능
call()은 전략(Strategy) 구현체로 분리 - Context가 전략을 주입받아
execute()에서 부가기능 + 핵심 기능 수행
장단점
- 상속이 아니라 합성이므로 OCP 준수에 유리
- 부가기능 변경 시 다른 Bean 주입으로 교체 가능
- 단점: 전략/컨텍스트 등 클래스 증가로 복잡성 증가
4) 템플릿 콜백 패턴(Template-Callback)
개념
- 전략 패턴과 유사
- 핵심 기능
call()을 함수형 파라미터(콜백) 로 받아 더 간단히 사용 가능
5) 프록시(Proxy)
개념
- 요청을 중간에서 가로채 대신 최종 목적지로 전달
- 중간에서 데이터 변경 가능
- 최종 목적지 호출 없이 캐시 반환 등도 가능
- 클라이언트는 “프록시인지 실제 대상인지” 몰라도 결과만 받으면 됨
6) 프록시 패턴 vs 데코레이터 패턴
공통
- 구현 형태(래핑/위임)는 유사
차이(의도)
- 프록시: 접근 제어
- 지연 로딩, 권한 체크, 캐시, 원격 호출
- 데코레이터: 기능 확장/부가기능 추가
- 로깅, 트랜잭션, 시간 측정, 압축/암호화, 포맷팅
체이닝
Proxy/Decorator -> Proxy/Decorator -> Target형태로 체인 구성 가능
7) JDK 동적 프록시
해결하는 문제
- 여러 계층(Controller/Service/Repository)에 데코레이터/프록시를 적용하려면
- 타겟마다 프록시 클래스를 만들어야 하는 문제가 큼
- JDK 동적 프록시는 프록시 클래스(핸들러) 재사용 가능
플로우
client.callproxy -> handler.invokehandler에서 부가기능 수행- 실제 타겟 메서드 실행
- 역방향 반환
유의점
- 인터페이스가 반드시 필요
8) CGLIB
개념
- JDK 동적 프록시의 “인터페이스 필요” 제약을 보완
- 바이트코드 조작으로 타겟 클래스의 서브클래스 생성
MethodInterceptor를 통해 부가기능 수행 후 부모(원본) 로직 호출
제약
final class/final method면 상속/오버라이드 불가 → 프록시 불가/적용 제한
9) 프록시 팩토리(ProxyFactory)
역할
- 인터페이스 유무로 JDK 동적 프록시 vs CGLIB 선택
- 기술별 진입점이 달라도 Advice 기반으로 통합해 사용
10) 어드바이저(Advisor)
- Advice: 부가기능 정의
- Pointcut: 어디에 적용할지 정의
- Advisor: Pointcut 1 + Advice 1 조합
- 하나의 타겟에 여러 Advisor 적용 가능
11) 빈 후처리기(BeanPostProcessor)
개념
- 빈은 컨테이너에 최종 등록되기 전에 후처리 단계를 거칠 수 있음
- 이 단계에서 프록시 적용 가능
효과
- 원래는 빈마다 ProxyFactory로 수동 감싸기가 필요했지만
- 후처리기(자동 프록시 생성기)가
- 등록된 Advisor(포인트컷+어드바이스) 기준으로
- 자동으로 프록시를 만들어 교체해줌
- 직접 만들지 않아도 스프링이 자동 구성해주는 경우가 많음
12) AOP 실제 작동 순서(프록시 기반)
- 빈 인스턴스 생성/초기화
- 자동 프록시 생성기(빈 후처리기)가 해당 빈에 적용 가능한 Advisor 조회
- 매칭되면 ProxyFactory로 프록시 생성(JDK/CGLIB)
- 프록시를 빈으로 최종 등록
13) @Around vs @Before
@Around: 메서드 전/후 모두 가능proceed()를 호출해야 실제 메서드가 실행됨(미호출 시 위험)
@Before: 메서드 “전”만- 단순 전처리만 필요하면
@Before가 더 안전할 수 있음
- 단순 전처리만 필요하면
14) AOP 내부 호출(Self-invocation) 문제
현상
- 같은 클래스 내부에서
a()가b()를 호출하면 AOP가b()에 적용되지 않음
이유
- AOP는 프록시를 통해 들어오는 호출만 잡는데
- 내부 호출은
this.b()로 프록시를 거치지 않음
해결
- 일반적으로 별도 클래스로 분리해서 프록시 경유 호출로 만든다
1) ThreadLocal
문제
- ThreadLocal을 사용하기 좋은 상황을 한 줄로 설명하라.
- ThreadLocal 사용 시 “값이 다음 작업에 남는” 문제가 생기는 이유를 말하라.
- ThreadLocal 사용 후 반드시 해야 하는 조치를 쓰라.
답
- 여러 스레드가 공유하는 Bean이 아니라, 한 스레드 내부에서 전역 접근이 필요할 때.
- 스레드풀 등에서 스레드가 재사용되면 이전 ThreadLocal 값이 남을 수 있어서.
- 사용 완료 후
remove()로 제거한다.
2) 템플릿 메서드 패턴
문제
- 템플릿 메서드 패턴의 목적을 한 줄로 쓰라.
- 템플릿 메서드 패턴에서 보통
execute()와call()의 역할을 구분해 설명하라. - 템플릿 메서드 패턴이 OCP에 취약해질 수 있는 이유를 쓰라.
답
- 핵심 기능과 부가기능을 분리해 핵심 기능만 교체 가능하게 한다.
call()은 핵심 기능 구현(변하는 부분),execute()는 부가기능 +call()호출(고정 흐름).- 상속 기반이라 부가기능 변경이 필요하면 부모 변경이 필요해 OCP 위배 가능.
3) 전략 패턴
문제
- 전략 패턴이 템플릿 메서드 패턴의 어떤 문제를 보완하는지 쓰라.
- 전략 패턴에서 Context(부가기능 담당)와 Strategy(핵심 기능)의 관계를 한 줄로 설명하라.
- 전략 패턴의 단점 2가지를 쓰라.
- 전략 패턴이 OCP에 유리한 이유를 한 줄로 쓰라.
답
- 상속으로 인한 결합/부모 변경 문제를 합성(주입)으로 보완한다.
- Context가 Strategy 구현체를 주입받아
execute()에서 부가기능 + 핵심 기능을 수행한다. - 클래스/객체 수 증가, 전략 선택/주입 설계로 복잡성 증가.
- 핵심/부가기능 교체를 객체 교체로 해결해 코어 수정이 줄어든다.
4) 템플릿 콜백 패턴
문제
- 템플릿 콜백 패턴이 전략 패턴과 유사한 점을 한 줄로 쓰라.
- 템플릿 콜백 패턴이 “더 간단해질 수 있는” 이유를 쓰라.
답
- 부가기능(템플릿)과 핵심 기능(콜백)을 분리해 조합한다.
- 핵심 기능을 함수형 파라미터로 받아 구현체 클래스를 줄일 수 있다.
5) 프록시(Proxy)
문제
- 프록시의 역할을 한 줄로 정의하라.
- 프록시가 할 수 있는 추가 기능 2가지를 쓰라.
- 클라이언트가 프록시를 몰라도 되는 이유를 한 줄로 쓰라.
답
- 요청을 중간에서 가로채 최종 목적지로 전달(또는 대체)하는 대리자.
- 요청/응답 데이터 변경, 캐시로 즉시 반환, 원격 호출/접근 제어 등.
- 클라이언트는 결과만 받으면 되고 구현(프록시/대상)을 알 필요가 없다.
6) 프록시 패턴 vs 데코레이터 패턴
문제
- 프록시 패턴과 데코레이터 패턴의 공통점 1가지를 쓰라.
- 프록시 패턴의 목적(키워드)을 쓰고 예시 2개를 쓰라.
- 데코레이터 패턴의 목적(키워드)을 쓰고 예시 2개를 쓰라.
- 체이닝 구성을 한 줄로 표현하라.
답
- 둘 다 래핑/위임 구조로 대상 호출을 감싼다.
- 접근 제어: 지연 로딩, 권한 체크, 캐시, 원격 호출 등.
- 기능 확장/부가기능 추가: 로깅, 트랜잭션, 시간 측정, 포맷팅 등.
Wrapper -> Wrapper -> Target형태로 여러 단계 체이닝 가능.
7) JDK 동적 프록시
문제
- JDK 동적 프록시가 해결하는 “반복 작업” 문제를 한 줄로 쓰라.
- JDK 동적 프록시의 동작 플로우를 순서대로 쓰라.
- JDK 동적 프록시의 제약 1가지를 쓰라.
답
- 타겟마다 프록시 클래스를 만들던 중복을 handler 재사용으로 줄인다.
client.call -> proxy -> handler.invoke -> 부가기능 -> target 메서드 실행 -> 반환- 인터페이스가 필요하다.
8) CGLIB
문제
- CGLIB가 JDK 동적 프록시의 어떤 제약을 보완하는지 쓰라.
- CGLIB의 동작 방식을 한 줄로 쓰라.
- CGLIB 사용 불가(또는 제한) 조건 2가지를 쓰라.
답
- 인터페이스가 없어도 클래스 기반으로 프록시 가능.
- 타겟 클래스를 상속한 서브클래스를 만들고
MethodInterceptor로 가로챈다. final class는 상속 불가,final method는 오버라이드 불가.
9) 프록시 팩토리(ProxyFactory)
문제
- 프록시 팩토리의 핵심 역할을 한 줄로 쓰라.
- 프록시 팩토리가 프록시 기술을 무엇 기준으로 선택하는지 쓰라.
- 프록시 기술이 달라도 공통으로 쓰는 개념(스프링 관점)을 쓰라.
답
- 프록시 생성 과정을 표준화하고 자동으로 프록시를 만든다.
- 인터페이스 유무(및 설정)에 따라 JDK 동적 프록시/CGLIB 선택.
- Advice(→ 내부적으로 인터셉터 체인)로 공통 처리한다.
10) 어드바이저(Advisor)
문제
- Advice와 Pointcut의 역할을 각각 한 줄로 쓰라.
- Advisor를 정의하라.
- 하나의 타겟에 여러 Advisor를 적용할 수 있는지 답하라.
답
- Advice: 부가기능 정의 / Pointcut: 적용 대상(위치) 정의.
- Pointcut 1 + Advice 1의 조합.
- 가능하다.
11) 빈 후처리기(BeanPostProcessor)
문제
- 빈 후처리기가 개입하는 시점을 한 줄로 쓰라.
- 빈 후처리기로 프록시 적용이 쉬워지는 이유를 한 줄로 쓰라.
- 수동 ProxyFactory 적용 방식의 단점을 한 줄로 쓰라.
답
- 빈이 컨테이너에 최종 등록되기 전/후(초기화 전후) 단계.
- 등록된 Advisor 기준으로 자동으로 프록시를 만들어 빈을 교체할 수 있어서.
- 빈마다 직접 감싸야 해서 중복/누락/복잡성이 증가한다.
12) AOP 실제 작동 순서(프록시 기반)
문제
- AOP 프록시가 만들어지는 단계 흐름을 순서대로 쓰라.
- “Advisor 매칭”은 언제 수행되는지 한 줄로 쓰라.
답
- 빈 인스턴스 생성/초기화 → 자동 프록시 생성기(BPP) 동작 → Advisor 조회/매칭 → ProxyFactory로 프록시 생성 → 프록시를 빈으로 최종 등록.
- 보통 빈 초기화 후 BPP 단계에서 수행된다.
13) @Around vs @Before
문제
- @Around와 @Before의 실행 범위를 각각 쓰라.
- @Around에서 반드시 필요한 호출 1가지를 쓰고, 누락 시 문제를 한 줄로 쓰라.
- “메서드 실행 전만 필요”할 때 @Before가 더 안전할 수 있는 이유를 쓰라.
답
- @Around: 전/후 / @Before: 전.
proceed()호출이 필요하며, 누락되면 실제 메서드가 실행되지 않는다.- proceed 누락 위험이 없어서 단순 전처리에 안전하다.
14) AOP 내부 호출(Self-invocation) 문제
문제
- 같은 클래스 내부 호출에서 AOP가 동작하지 않는 이유를 한 줄로 쓰라.
- 이 문제가 특히 자주 보이는 스프링 기능 2가지를 쓰라.
- 일반적인 해결 방법 1가지를 쓰라.
답
- 내부 호출은 프록시를 거치지 않고
this로 직접 호출되기 때문. @Transactional,@Cacheable(또는@Async) 등.- 호출 대상 메서드를 별도 클래스로 분리해 프록시 경유 호출로 만든다.
'김영한의 스프링 핵심 원리 - 고급편' 카테고리의 다른 글
| 김영한의 스프링 핵심 원리(고급편) - AOP 실무 예제 (0) | 2025.02.25 |
|---|---|
| 김영한의 스프링 핵심 원리(고급편) - 포인트컷 지시자(execution 등) (1) | 2025.02.25 |
| 김영한의 스프링 핵심 원리(고급편) - AOP의 포인트컷, AOP의 어드바이스 종류 (0) | 2025.02.25 |
| 김영한의 스프링 핵심 원리(고급편) - @Aspect, AOP (0) | 2025.02.24 |
| 김영한의 스프링 핵심 원리(고급편) - 빈 후처리기 (0) | 2025.02.22 |