이번 포스팅에서는 AOP에 관련된 Annotation(@)을 알아보도록 하겠습니다.
1. @Aspect
xxxxxxxxxxpublic class LogAop { ...}@Aspect Annotation의 경우 해당 Class가 횡단관심사(부가기능) Class임을 알려주는 Annotation입니다. @AspectAnnotation이 부여되었다고 해서 자동으로 Bean으로 등록되는것이 아니므로 따로 Bean으로 등록을 해주는 작업이 필요합니다. 물론 @Component등의 Annotation을 이용해도 됩니다.
2. @Around("Pointcut")
xxxxxxxxxxpublic class LogAop { ("execution(* com.java.ex.Car.accelerate(..))") public Object logging(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().toShortString(); try { System.out.println(methodName + "is Start."); Object obj = joinPoint.proceed(); return obj; }finally { System.out.println(methodName + "is Finish."); } }}@Around Annotation의 경우 앞선 포스팅에서 살펴보았듯이 Advice한 종류로 핵심관심사의 실패여부와 상관없이 전 후로 실행되도록 하는 Advice입니다. @Around Annotation의 속성값으로 PointCut을 전달해주어야 합니다. 위 코드에서 PointCut이 조금 복잡한 방법으로 작성된 것을 볼 수 있습니다. 아래의 Pointcut 표현식에서 알아보도록 하겠습니다.
3. @Pointcut
@Pointcut은 횡단관심사(부가기능)이 적용될 JoinPoint들을 정의한 것입니다. @PointcutAnnotation의 경우 조금 복잡한 표현식을 가지고 있습니다. 하나씩 예제를 살펴보며 적응할 수 있도록 해보겠습니다.
3.1 execution(접근제어자,반환형 패키지를 포함한 클래스 경로 메소드파라미터 )
("execution(public void get*())")퍼블릭형의 반환형이 없는(public void) 형태의 메소드 중 get으로 시작하는(get*) 모든 메소드중 파라미터가 존재하지 않는(()) 메소드들에게 적용
("execution(* *(..))")첫번째 *기호는 접근제어자와 반환형 모두를 상관하지 않고 적용하겠다는 의미입니다. 두번째 *기호는 어떠한 경로에 존재하는 클래스도 상관하지 않고 적용하겠다는 의미입니다. 마지막으로 (..)은 메소드의 파라미터가 몇개가 존재하던지 상관없이 실행하는 경우를 의미합니다.
("execution(* com.java.ex.Car.accelerate())")첫번째 *기호는 역시 접근제어자, 반환형을 상관하지 않는다는 의미이며, com.java.ex.Car.accelerate()는 해당 Class의 accelerate()(파라미터가 없는) 메소드가 호출될 때 실행하는 경우를 의미합니다.
xxxxxxxxxx("execution(* com.java..*.*())")위와 거의 비슷하지만 com.java..부분 즉, ..부분이 조금 다른것을 볼 수 있습니다. ..의 경우 해당 패키지를 포함한 모든 하위패키지에 적용을 한다는 의미입니다. 해석한다면 접근제어자, 반환형을 상관하지 않고 com.java패키지를 포함한 모든 하위디렉토리의 모든 Class의 모든 파라미터가 존재하지 않는 메소드에 적용한다는 의미입니다.
예제
public class LogAop { ("execution(public void com.java.ex.Car.*())") public Object logging(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().toShortString(); try { System.out.println(methodName + "is Start."); Object obj = joinPoint.proceed(); return obj; }finally { System.out.println(methodName + "is Finish."); } }}
3.2 within(Class의 경로)
패키지내의 모든 메소드에 적용할 때 사용합니다.
("within(com.java.ex.*)")com.java.ex.하위의 모든 클래스의 모든 메소드에 적용하겠다는 의미입니다.
("within(com.java.ex..*)")com.java.ex.패키지의 하위 패키지를 포함한 모든 클래스의 모든 메소드에 적용하겠다는 의미입니다.
("within(com.java.ex.Car)")com.java.ex.Car 클래스안의 모든 메소드에 적용하겠다는 의미입니다.
예제
public class LogAop { ("within(com.java.ex.*)") public Object logging(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().toShortString(); try { System.out.println(methodName + "is Start."); Object obj = joinPoint.proceed(); return obj; }finally { System.out.println(methodName + "is Finish."); } }}
3.3 Bean(bean id)
해당 bean id를 가지고있는 bean의 모든 메소드에 적용한다는 의미입니다.
xxxxxxxxxx@Pointcut(bean(car))
car라는 bean id를 가지고있는 bean에게 적용한다는 의미입니다.
예제
("bean(car)") public Object logging(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().toShortString(); try { System.out.println(methodName + "is Start."); Object obj = joinPoint.proceed(); return obj; }finally { System.out.println(methodName + "is Finish."); } }
3.4 Annotation
/**
* 이 어노테이션을 부여하면 해당 메소드의 성능을 로깅합니다.
*/
@Documented
@Target(ElementType.METHOD)
public @interface PerfLogging {
}
@Aspect
public class LogAop {
@Around("@annotation(PerfLogging)")
public Object logging(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().toShortString();
try {
System.out.println(methodName + "is Start.");
Object obj = joinPoint.proceed();
return obj;
}finally {
System.out.println(methodName + "is Finish.");
}
}
}
4. AOP ERROR
위와 같은 오류가 발생할 시에는 PointCut 표현식의 오류일 확률이 높습니다. PointCut 표현식을 다시 한번 확인해 보세요.
'FrameWork > Spring' 카테고리의 다른 글
| Spring - Model을 이용하여 View에 데이터 넘겨주기 - 6 (4) | 2019.04.03 |
|---|---|
| Spring - Spring MVC 동작과정 -5 (0) | 2019.04.03 |
| Spring - Spring을 왜 사용하나요?(AOP) - 3 (2) | 2019.03.29 |
| Spring - @Bean 어노테이션과 @Component 어노테이션(DI) - 2 (6) | 2019.03.26 |
| Spring - Spring을 왜 사용하나요?(DI) - 1 (15) | 2019.03.26 |