이번 포스팅에서는 AOP
에 관련된 Annotation(@)
을 알아보도록 하겠습니다.
1. @Aspect
xxxxxxxxxx
public class LogAop {
...
}
@Aspect
Annotation의 경우 해당 Class가 횡단관심사(부가기능) Class임을 알려주는 Annotation입니다. @Aspect
Annotation이 부여되었다고 해서 자동으로 Bean으로 등록되는것이 아니므로 따로 Bean으로 등록을 해주는 작업이 필요합니다. 물론 @Component등의 Annotation을 이용해도 됩니다.
2. @Around("Pointcut")
xxxxxxxxxx
public 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
들을 정의한 것입니다. @Pointcut
Annotation의 경우 조금 복잡한 표현식을 가지고 있습니다. 하나씩 예제를 살펴보며 적응할 수 있도록 해보겠습니다.
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 |