[Spring5입문] 프록시 생성 방식

2021. 8. 11. 14:33CSE/Spring

- 스프링은 AOP를 위한 프록시 객체를 생성할 때, 실제 생성할 빈 객체가 인터페이스를 상속하면 인터페이스를 이용해서 프록시를 생성한다.

=> 따라서 아래 코드처럼 빈의 실제 타입이 RecCalculator라고 하더라도, 빈 객체는 Calculator 인터페이스를 상속받은 프록시 타입이 된다.

//설정 클래스
@Bean
public Calculator calculator(){
	return new RecCalculator();
}

//자바 코드
RecCalculator cal = ctx.getBean("calculator", RecCalculator.class);
//calculator 빈의 실제 타입은 Calculator을 상속한 프록시 타입이므로
//RecCalculator로 타입 변환을 할 수 없기 때문에 익셉션 발생

- 빈 객체가 인터페이스를 상속할 때, 인터페이스가 아닌 클래스를 이용해서 프록시를 생성하고 싶다면

=> @EnableAspectJAutoProxy 애노테이션의 proxyTargetCalss 속성을 true로 지정하면 된다.

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppCtx{
  @Bean
  public Calculator calculator(){
      return new RecCalculator();
  }
}

//자바 코드
RecCalculator cal = ctx.getBean("calculator", RecCalculator.class);
//calculator 빈의 실제 타입은 RecCalculator를 상속받았으므로
//타입 변환 가능

 

1. execution 명시자 표현식

- Pointcut 설정의 execution 명시자는 Advice를 적용할 메서드를 지정할 때 다음과 같이 사용한다.

execution(수식어패턴? 리턴타입패턴 클래스이름패턴?메서드이름패턴(파라미터패턴))
  • 수식어 패턴 : 생략 가능하며 public, protected 등이 온다. 스프링 AOP는 public 메서드에만 적용할수 있기 때문에 public만 의미있다.
  • 리턴타입패턴 : 리턴 타입을 명시한다
  • 클래스이름패턴, 메서드이름패턴 : 클래스 이름 및 메서드 이름을 패턴으로 명시
  • 파라미터패턴 : 매칭될 파라미터에 대해서 명시
  • * : 모든 값 표현
  • .. : 0개 이상이라는 의미 표현

 

2. Advice 적용순서

- 한 Pointcut에 여러 Advice를 적용할 수도 있다.

=> 어떤 Aspect가 먼저 적용될지는 스프링 프레임워크나 자바 버전에 따라 달라질 수 있다

=> 따라서 적용순서가 중요하다면 직접 순서를 지정해야 한다.

- @Order 애노테이션 : 적용 순서를 지정할 수 있다. 값이 작으면 먼저 적용한다.

 

3. @Around의 Pointcut 설정과 @Pointcut 재사용

- @Pointcut 애노테이션이 아닌 @Around 애노테이션에서 execution명시자를 직접 지정할 수도 있다.

@Aspect
public class ExeTimeAspect {

    @Around("execution(public * chap07..*(..))")
    public Object measure(ProceedingJoinPoint joinPoint) throws Throwable{
        ...
    }
}

- 만약 같은 Pointcut을 여러 Advice가 함께 사용한다면 공통 Pointcut을 재사용 할 수도 있다.

=> @Around의 execution으로 Pointcut의 완전한 클래스 이름을 포함한 메서드 이름을 주면 된다.