진짜 개발자
본문 바로가기

FrameWork/Spring

Spring - AOP관련 Annotation - 4

728x90
### AOP 분석

이번 포스팅에서는 AOP에 관련된 Annotation(@)을 알아보도록 하겠습니다.

 

1. @Aspect

@Aspect Annotation의 경우 해당 Class가 횡단관심사(부가기능) Class임을 알려주는 Annotation입니다. @AspectAnnotation이 부여되었다고 해서 자동으로 Bean으로 등록되는것이 아니므로 따로 Bean으로 등록을 해주는 작업이 필요합니다. 물론 @Component등의 Annotation을 이용해도 됩니다.

 

 

2. @Around("Pointcut")

@Around Annotation의 경우 앞선 포스팅에서 살펴보았듯이 Advice한 종류로 핵심관심사의 실패여부와 상관없이 전 후로 실행되도록 하는 Advice입니다. @Around Annotation의 속성값으로 PointCut을 전달해주어야 합니다. 위 코드에서 PointCut이 조금 복잡한 방법으로 작성된 것을 볼 수 있습니다. 아래의 Pointcut 표현식에서 알아보도록 하겠습니다.

 

 

3. @Pointcut

@Pointcut횡단관심사(부가기능)이 적용될 JoinPoint들을 정의한 것입니다. @PointcutAnnotation의 경우 조금 복잡한 표현식을 가지고 있습니다. 하나씩 예제를 살펴보며 적응할 수 있도록 해보겠습니다.

 

3.1 execution(접근제어자,반환형 패키지를 포함한 클래스 경로 메소드파라미터 )

퍼블릭형의 반환형이 없는(public void) 형태의 메소드 중 get으로 시작하는(get*) 모든 메소드중 파라미터가 존재하지 않는(()) 메소드들에게 적용

 

첫번째 *기호는 접근제어자와 반환형 모두를 상관하지 않고 적용하겠다는 의미입니다. 두번째 *기호는 어떠한 경로에 존재하는 클래스도 상관하지 않고 적용하겠다는 의미입니다. 마지막으로 (..)은 메소드의 파라미터가 몇개가 존재하던지 상관없이 실행하는 경우를 의미합니다.

 

첫번째 *기호는 역시 접근제어자, 반환형을 상관하지 않는다는 의미이며, com.java.ex.Car.accelerate()는 해당 Class의 accelerate()(파라미터가 없는) 메소드가 호출될 때 실행하는 경우를 의미합니다.

 

위와 거의 비슷하지만 com.java..부분 즉, ..부분이 조금 다른것을 볼 수 있습니다. ..의 경우 해당 패키지를 포함한 모든 하위패키지에 적용을 한다는 의미입니다. 해석한다면 접근제어자, 반환형을 상관하지 않고 com.java패키지를 포함한 모든 하위디렉토리의 모든 Class의 모든 파라미터가 존재하지 않는 메소드에 적용한다는 의미입니다.

 

예제

 

 

3.2 within(Class의 경로)

패키지내의 모든 메소드에 적용할 때 사용합니다.

 

com.java.ex.하위의 모든 클래스의 모든 메소드에 적용하겠다는 의미입니다.

 

com.java.ex.패키지의 하위 패키지를 포함한 모든 클래스의 모든 메소드에 적용하겠다는 의미입니다.

 

com.java.ex.Car 클래스안의 모든 메소드에 적용하겠다는 의미입니다.

 

예제

 

 

3.3 Bean(bean id)

해당 bean id를 가지고있는 bean의 모든 메소드에 적용한다는 의미입니다.

 

car라는 bean id를 가지고있는 bean에게 적용한다는 의미입니다.

 

예제

 

3.4 Annotation

또는 사용자가 직접 만든 Annotation에 기반해 Aspect를 적용할 수도 있습니다.

위와 같이 간단히 Annotation을 만들어줍니다. 주석을 달아주면 더더욱 좋을것 같습니다.

@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.");
}
}
}
그 후 어드바이스 어노테이션안에 @annotation("어노테이션 class명") 을 입력해주면 됩니다.



4. AOP ERROR

위와 같은 오류가 발생할 시에는 PointCut 표현식의 오류일 확률이 높습니다. PointCut 표현식을 다시 한번 확인해 보세요.



만약 위와 같은 에러도 나타나지 않고 그냥 메소드만 출력되는 경우에는 IOC Container를 통해 해당 Bean이 생성되었는지를 생각해야합니다. 

Spring AOP의 경우 AOP를 제공받을 Bean를 IOC Container에 의해 생성될 때 ProxyBean을 만들어서 AOP를 제공하기 때문에 직접 생성하는 것이 아니라 꼭 IOC Container에 의해 생성되도록 해야합니다.