스프링부트

[스프링] 빈 후처리기

딤섬뮨 2022. 9. 19. 10:54
728x90

빈 후처리기란?

 

빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 전에 조작을 하고 싶다면 빈 후처리기를 사용한다.

이런식으로 다른 빈 으로 바꿔칠 수도 있다.

  1. 생성 : 스프링 빈 대상이 되는 객체를 생성
  2. 전달 : 생성된 객체를 빈 저장소에 등록하기 직전, 빈 후처리기로 전달
  3. 후처리 작업 : 전달된 스프링 빈 객체를 조작한다.
  4. 등록 : 후처리기는 객체를 조작 후 조작된 객체를 반환하는데, 이 반환된 객체가 빈으로 등록, 스프링 컨테이너로 등록된다.

 

이러한 빈 후처리기를 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여러개가 붙여지는 개념이다.

 

728x90

'스프링부트' 카테고리의 다른 글

AppConfig를 언제 써야하는가?  (2) 2022.09.07
[스프링] 전략 패턴  (3) 2022.08.19
[스프링]ThreadLocal  (4) 2022.08.09
[스프링부트] 서블릿 Servlet  (0) 2022.07.22
[스프링부트] 개발하다가 알게된 Entity  (0) 2022.07.16