이번엔 @Aspect Annotation을 이용해서 AOP를 설정해보도록 하자....
이것 역시 XML 스키마를 이용하여 설정한다..
일단 xmlns에 aop를 추가해주고...
위 태그를 사용하면 @Aspect Annotation이 사용된 클래스의 Advice 및 Pointcut을 알맞은 빈 객체에 적용한다...
실제 @Aspect Annotation을 사용한 클래스를 살펴보자..
앞서 살펴보았던 POJO를 이용한 설정과 매우 유사하다..
단지 소스 코드에 직접 입력하느냐 설정 파일에 설정하느냐의 차이만 있을 뿐이다...
위의 TestAspect를 생성해주면 test.aspect 패키지의 모든 클래스의 모든 메소드에 AOP가 적용이 된다..
위의 예제는 test.aspect.TestService의 모든 메소드에 TestAspect가 적용되는 설정이다...
그렇다면 도대체 AspectJ의 Pointcut 표현식이 어떤 뜻인지 궁금해진다..
Spring에서 제공하는 AspectJ의 Pointcut 명시자는 execution과 within 그리고 bean 명시자이다..
먼저 Advice를 적용할 메소드를 명시할 때 사용하는 execution부터 살펴보도록 하자..
execution([접근명시자패턴] 리턴타입패턴 이름패턴(파라미터패턴)) 접근명시자패턴은 public, protected, private 등을 사용할 수가 있고 생략 가능하다..
리턴타입패턴은 가능한 모든 리턴 타입을 사용할 수 있고..
이름패턴에는 패키지를 포함한 클래스 이름과 메소드 이름을 사용하고...
파라미터패턴에는 매칭될 파라미터에 대해 명시해준다...
또한 모든 패턴에는 * 를 이용하여 모든 값을 명시할 수 있고 ..을 이용하여 0개 이상이라는 의미를 표현할 수 있다..
예제를 살펴보자....
execution(public void set*(..)) : 리턴 타입이 void이고 set으로 시작하는 파라미터 0개 이상인 public 메소드
execution(* test.aspect.*.*()) : test.aspect 패키지의 파라미터가 없는 모든 메소드
execution(* test.aspect..*.*(..)) : test.aspect 패키지 및 하위 패키지에 파라미터가 0개 이상인 메소드
execution(void test.aspect.TestService.test()) : 리턴 타입이 void인 TestService의 test 메소드 호출
execution(* test*(*)) : test로 시작하는 파라미터 1개를 갖는 메소드
execution(* test*(*, *)) : test로 시작하는 파라미터 2개를 갖는 메소드
execution(* test*(Integer, ..)) : test로 시작하고 첫번째 파라미터는 Integer이고 1개 이상의 파라미터를 갖는 메소드
자세한 내용은 첨부로 올리는 AspectJ Syntax를 참고하도록 하자..
within 명시자는 특정 메소드가 아닌 특정 타입에 속하는 메소드를 명시할 때 사용한다...
within(test.aspect.TestService) : TestService의 모든 메소드
within(test.aspect.*) : test.aspect 패키지의 모든 메소드
within(test.aspect..*) : test.aspect 패키지 및 하위 패키지의 모든 메소드
bean 명시자는 빈의 이름을 이용하여 Pointcut을 정의한다.
bean(test) : 이름이 test인 빈의 메소드
bean(*test) : 이름이 test로 끝나는 빈의 메소드
이상 Spring에서 제공하는 AspectJ 표현식을 알아보았다..
위의 각각의 표현식은 다음과 같이 &&와 ||를 이용하여 연결할 수 있다..
@After("execution(public * get*()) ||execution(public * set*(..))")
이상으로 Spring의 AOP에 대하여 알아보았다.
이것 역시 XML 스키마를 이용하여 설정한다..
일단 xmlns에 aop를 추가해주고...
위 태그를 사용하면 @Aspect Annotation이 사용된 클래스의 Advice 및 Pointcut을 알맞은 빈 객체에 적용한다...
실제 @Aspect Annotation을 사용한 클래스를 살펴보자..
앞서 살펴보았던 POJO를 이용한 설정과 매우 유사하다..
단지 소스 코드에 직접 입력하느냐 설정 파일에 설정하느냐의 차이만 있을 뿐이다...
위의 TestAspect를 생성해주면 test.aspect 패키지의 모든 클래스의 모든 메소드에 AOP가 적용이 된다..
위의 예제는 test.aspect.TestService의 모든 메소드에 TestAspect가 적용되는 설정이다...
그렇다면 도대체 AspectJ의 Pointcut 표현식이 어떤 뜻인지 궁금해진다..
Spring에서 제공하는 AspectJ의 Pointcut 명시자는 execution과 within 그리고 bean 명시자이다..
먼저 Advice를 적용할 메소드를 명시할 때 사용하는 execution부터 살펴보도록 하자..
execution([접근명시자패턴] 리턴타입패턴 이름패턴(파라미터패턴)) 접근명시자패턴은 public, protected, private 등을 사용할 수가 있고 생략 가능하다..
리턴타입패턴은 가능한 모든 리턴 타입을 사용할 수 있고..
이름패턴에는 패키지를 포함한 클래스 이름과 메소드 이름을 사용하고...
파라미터패턴에는 매칭될 파라미터에 대해 명시해준다...
또한 모든 패턴에는 * 를 이용하여 모든 값을 명시할 수 있고 ..을 이용하여 0개 이상이라는 의미를 표현할 수 있다..
예제를 살펴보자....
execution(public void set*(..)) : 리턴 타입이 void이고 set으로 시작하는 파라미터 0개 이상인 public 메소드
execution(* test.aspect.*.*()) : test.aspect 패키지의 파라미터가 없는 모든 메소드
execution(* test.aspect..*.*(..)) : test.aspect 패키지 및 하위 패키지에 파라미터가 0개 이상인 메소드
execution(void test.aspect.TestService.test()) : 리턴 타입이 void인 TestService의 test 메소드 호출
execution(* test*(*)) : test로 시작하는 파라미터 1개를 갖는 메소드
execution(* test*(*, *)) : test로 시작하는 파라미터 2개를 갖는 메소드
execution(* test*(Integer, ..)) : test로 시작하고 첫번째 파라미터는 Integer이고 1개 이상의 파라미터를 갖는 메소드
자세한 내용은 첨부로 올리는 AspectJ Syntax를 참고하도록 하자..
within 명시자는 특정 메소드가 아닌 특정 타입에 속하는 메소드를 명시할 때 사용한다...
within(test.aspect.TestService) : TestService의 모든 메소드
within(test.aspect.*) : test.aspect 패키지의 모든 메소드
within(test.aspect..*) : test.aspect 패키지 및 하위 패키지의 모든 메소드
bean 명시자는 빈의 이름을 이용하여 Pointcut을 정의한다.
bean(test) : 이름이 test인 빈의 메소드
bean(*test) : 이름이 test로 끝나는 빈의 메소드
이상 Spring에서 제공하는 AspectJ 표현식을 알아보았다..
위의 각각의 표현식은 다음과 같이 &&와 ||를 이용하여 연결할 수 있다..
@After("execution(public * get*()) ||execution(public * set*(..))")
이상으로 Spring의 AOP에 대하여 알아보았다.
TAG Spring