📍빈 후처리기
빈 등록 과정
1. 생성- 스프링 빈 대상이 되는 객체를 생성한다. ( @Bean` , 컴포넌트 스캔 모두 포함)
2. 전달- 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달한다.
3. 후 처리 작업- 빈 후처리기는 전달된 스프링 빈 객체를 조작하거나 다른 객체로 바뀌치기 할 수 있다.
4. 등록- 빈 후처리기는 빈을 반환한다. 전달 된 빈을 그대로 반환하면 해당 빈이 등록되고, 바꿔치기 하면 다른 객 체가 빈 저장소에 등록된다.
빈 후처리기를 사용하려면 `BeanPostProcessor` 인터페이스를 구현하고 스프링 빈으로 등록하면 된다.
- postProcessBeforeInitialization 객체 생성 이후에 @PostConstruct 같은 초기화가 발생하기 전에 호출되는 포스트 프로세서
- postProcessAfterInitialization 객체 생성 이후에 `@PostConstruct 같은 초기화가 발생한 다음에 호출되는 포스트 프로세서
모든 스프링 빈들에 프록시를 적용할 필요는 없다. 여기서는 특정 패키지와 그 하위에 위치한 스프링 빈들만 프록시를 적용한다.
프록시 적용 대상의 변환 값을 보면 원본 객체 대신에 프록시 객체를 반환한다. 따라서 스프링 컨테이너에 원본 객체 대신에 프록시 객체가 스프링 빈으로 등록된다. 원본 객체는 스프링 빈으로 등록되지 않는다.
프록시 적용 대상 여부 체크
- 애플리케이션을 실행해서 로그를 확인해보면 우리가 직접 등록한 스프링 빈 뿐만 아니라 스프링부트가 기본으로 등록하는 수많은 빈들이 빈 후처리기에 넘어온다. 그래서 어떤 빈을 프록시로 만들 것인지 기준이 필요하다. 여기서는 간단히 basePackage를 사용해서 특정 패키지를 기준으로 해당 패키지와 그 하위 패키지의 빈들을 프록시로 만든다
- 스프링부트가 기본으로 제공하는 빈 중에는 프록시 객체를 만들 수 없는 빈들도 있다. 따라서 모든 객체를 프록시로 만들 경우 오류가 발생한다.
✓문제 해결
1) 너무 많은 설정
2) 컴포넌트 스캔-> 프록시를 원본 객체 대신에 스프링 컨테이너에 빈으로 등록해야 한다. 그런데 컴포넌트 스캔은 원본 객체를 스프링 빈으로 자동으로 등록하기 떄문에 프록시 적용이 불가능하다. 이제 빈후처리기 덕분에 컴포넌트 스캔처럼 스프링이 직접 대상을 빈으로 등록하는 경우에도 중간에 빈 등록 과정을 가로채서 원본 대신에 프록시를 스프링 빈으로 등록할 수 있다.
포인트컷은 다음 두 곳에서 사용된다
1. 프록시 적용 대상 여부를 체크해서 꼭 필요한 곳에만 프록시를 적용(빈 후처리기-자동 프록시 생성)
2. 프록시의 어떤 메서드가 호출 되었을 때 어드바이스를 적용할 지 판단(프록시 내부)
🌟🌟 포인트컷 사용
1. 프록시 적용 여부 판단-생성 단계
-자동 프록시 생성기는 포인트컷을 사용해서 해당 빈이 프록시를 생성할 필요가 있는지 없는지 체크한다
-클래스+메서드 조건을 모두 비교한다. 이때 모든 메서드를 체크하는데 포인트컷 조건에 하나하나 매칭해본다. 만약 조건에 맞는 것이 하나라도 있으면 프록시를 생성한다.
ex. orderControllerV1은 request(), noLog()가 있다. 여기에서 request()가 조건에 만족하므로 프록시를 생성한다.
-만약 조건에 맞는 것이 하나도 없으면 프록시를 생성할 필요가 없으므로 프록시를 생성하지 않는다.
2. 어드바이스 적용 여부 판단-사용 단계
-프록시가 호출되었을 때 부가 기능인 어드바이스를 적용할지 말지 포인트컷을 보고 판단한다
ex. orderControllerV1의 request()는 현재 포인트컷 조건에 만족하므로 프록시는 어드바이스를 먼저 호출하고 target을 호출한다
noLog()는 현재 포인트컷 조건에 만족하지 않으므로 어드바이스를 호출하지 않고 바로 target만 호출한다
✓프록시를 모든 곳에 생성하는 것은 비용 낭비이다. 꼭 필요한 곳에 최소한의 프록시를 적용해야 한다. 그래서 자동 프록시 생성기는 모든 스프링 빈에 프록시를 적용하는 것이 아니라 포인트컷으로 한번 필터링해서 어드바이스가 사용될 가능성이 있는 곳에만 프록시를 생성한다
🌟하나의 프록시, 여러 어드바이저
- advisor1의 포인트컷만 만족 -> 프록시 1개 생성, 프록시에 advisor1만 포함
- advisor1, advisor2의 포인트컷을 모두 만족 -> 프록시 1개 생성, 프록시에 advisor1, advisor2 모두 포함
- advisor1, advisor2의 포인트컷을 모두 만족하지 않음 -> 프록시가 생성되지 않음
'스터디 > Spring' 카테고리의 다른 글
[SPRING 고급] 포인트컷 지시자 (0) | 2025.01.07 |
---|---|
[SPRING 고급] @Aspect와 스프링 AOP (0) | 2025.01.03 |
[SPRING 고급] 프록시팩토리와 포인트컷,어드바이스,어드바이저 (1) | 2024.12.29 |
[SPRING 고급] JDK 동적 프록시와 CGLIB (1) | 2024.12.27 |
[SPRING 고급] 프록시 패턴과 데코레이터 패턴 (0) | 2024.12.24 |