빈 후처리기란?
빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 전에 조작을 하고 싶다면 빈 후처리기를 사용한다.
이런식으로 다른 빈 으로 바꿔칠 수도 있다.
- 생성 : 스프링 빈 대상이 되는 객체를 생성
- 전달 : 생성된 객체를 빈 저장소에 등록하기 직전, 빈 후처리기로 전달
- 후처리 작업 : 전달된 스프링 빈 객체를 조작한다.
- 등록 : 후처리기는 객체를 조작 후 조작된 객체를 반환하는데, 이 반환된 객체가 빈으로 등록, 스프링 컨테이너로 등록된다.
이러한 빈 후처리기를 BeanPostProcessor 인터페이스를 구현하여서 스프링 빈으로 등록하여 사용하는 방법도 있으나 너무 많은 설정을 해야하고,컴포넌트 스캔을 대상으로 하는 경우 사용이 불가능하다.
따라서 스프링이 제공하는 빈 후처리기를 사용한다.
<스프링이 제공하는 빈 후처리기 사용>
1. build.gradle 추가
implementation 'org.springframework.boot:spring-boot-starter-aop'
자동 프록시 생성기 - Auto Proxy Creator
앞서 이야기한 스프링 부트 자동 설정으로 AnnotationAwareAspectAutoProxyCreator라는 빈 후처리기가 스프링 빈에 자동 등록된다.
자동으로 프록시를 생성해주는 빈 후처리기!
이 빈 후처리기는 스프링 빈으로 등록 된 Advisor를 찾아서 프록시가 필요한 곳에 자동으로 프록시를 적용한다.
Advisor안에는 Pointcut과 Advice가 모두 포함됨.
Advisor만 안다면 그 안에 있는 poincut 이 스프링 빈 적용 가능성을 검토해줄 것이다.
(필기 날림체 어쩔 ..ㅋㅋㅋ)
여튼 A객체가 들어오면 프록시로 바꿔주는데 이때 Pointcut으로 바꿔줄지 말지 결정하고
프록시로 바뀌면 프록시를 등록한다. 물론 프록시로 변환 안되면 A객체 그대로 등록해준다.
@Configuration
public class AutoProxyConfig {
@Bean
public Advisor advisor1(LogTrace logTrace){
//pointcut 설정해주기 - 메소드와 이름 일치 여부
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.setMappedNames("show*","newArticleForm*");
//advice 추가
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
//Advisor(advice + pointcut) 설정
return new DefaultPointcutAdvisor(pointcut,advice);
}
}
간단하게 적용
@Import(AutoProxyConfig.class)
@SpringBootApplication
public class ProjectCrudApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectCrudApplication.class, args);
}
@Bean
public LogTrace logTrace(){
return new ThreadLocalLogTrace();
}
}
잘 실행 됩니당
pointcut에 설정 안한 edit* 함수를 호출하면?
로그가 찍히지 않음을 보며 pointcut이 제대로 설정 되었슴
포인트컷은 2가지에 사용된다
1. 프록시 적용대상 여부를 체크하여 꼭 필요한 곳에만 프록시 적용. 해당 빈이 프록시로 변환해야할지 말지
클래스와 메서드 조건을 모두 확인한다. 포인트컷 조건에 하나하나 매칭해봄
2. 어떤 메서드를 호출 하였을 때 어드바이스를 적용할지 판단.
edit * 에는 적용 X , show* 에는 부가기능 적용
현재는 프록시를 생성하면 스프링에 있는 모든 메서드가 로그로 날라온다.
이를방지하기 위해 AspectJExpressionPointcut으로 좀더 자세한 필터링을 해준다.
예시로
AspectJExpressionPointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* hello.proxy.app..*(..)));
* : 모든 반환 타입
hello.proxy.app.. :해당 패키지와 하위 패키지
*(..): 모든 메서드 이름
스프링 빈에 advisor가 2개 적용된다면 프록시는 몇개 생성 될까?
-> 단 한개 생성된다
그 한개에 advisor여러개가 붙여지는 개념이다.
'스프링부트' 카테고리의 다른 글
AppConfig를 언제 써야하는가? (2) | 2022.09.07 |
---|---|
[스프링] 전략 패턴 (3) | 2022.08.19 |
[스프링]ThreadLocal (4) | 2022.08.09 |
[스프링부트] 서블릿 Servlet (0) | 2022.07.22 |
[스프링부트] 개발하다가 알게된 Entity (0) | 2022.07.16 |