Aspect로 만들기 위해선 클래스 위에 @Aspect 어노테이션을 붙여야 한다. 이를 통해 프록시 패턴으로 동작하게 된다.
이후 jointPoint를 정해줘야 한다. @Before, @After, @After, @AfterReturning ... 등이 있다. 이 때 어노테이션 값으로 pointcut을 지정해줄 수 있다.
@Aspect
@Component
public class AopTest {
@Before("execution(public void addAccount())")
public void beforeAddAccount() {
log.info("execute addAccount")
}
}
위의 간단한 형태는 @Before를 사용했기 때문에 addAccount 메소드가 실행하기전에 밑에서 정의된 메소드가 실행된다.
포인트컷
- execution()이 달려있으면 주어진 메소드의 실행에 적용된다. 포인트컷 표현식 언어를 사용하여 메소드를 매칭하는 조건을 정의할 수 있다.
- 접근제어자(public, ..) 패턴, 리턴 타입 패턴, 선언 타입 패턴(메소드가 들어있는 클래스명), 메소드 이름 패턴, 파라미터 패턴, 예외 패턴이 있다.
- 여기서 접근제어자 패턴, 선언 타입 패턴, 예외 패턴은 선택 사항이다.
- 예를 들어 execution(public void com.rosoa0475.aopdemo.Account.addAccount())가 있다.
- 위와 같이 execution(public void addAccount())는 모든 클래스에 존재하는 addAccount 메소드 실행될 때이다.
- execution(public void add*())에서 *는 add로 시작하는 모든 것을 뜻한다. 즉 이름이 add로 시작하는 public과 void를 가진 메소드에 적용한다는 것이다. *를 와일드 카드라 한다. 와일드 카드는 모든 패턴에 적용할 수 있다.
- execution(public * add*()) 은 리턴 타입 패턴에 와일드 카드를 사용한 경우이다
- 마지막으로 파라미터 패턴에 대한 와일드 카드이다. ()의 경우 인자가 없는 경우이고, (*)의 경우 인자가 1개, (..)은 0개 이상의 인자를 가지는 메소드에 매칭된다. 파라미터 타입은 상관없다. 오로지 개수만을 따진다. 하지만 파라미터 타입을 지정한다면 타입까지 매칭된 메소드만 적용된다. execution(* add(Integer, *))와 같이 사용 가능하다.
https://ittrue.tistory.com/233 추가적인 포인트컷은 다음 블로그를 참고하자.
포인트컷 주의 사항 : intellij ultimate의 경우 와일드 카드 사용시 다른 라이브러리와 충돌되므로 com.rosoa0475을 붙여줘야 한다. 이 때 맨 마지막은 메소드명이므로 꼭 클래스 파일까지의 경로까지는 와야 한다.
포인트컷 재사용성 : 아래와 같이 포인트컷 선언을 통해 재사용성을 높일 수 있다. 이 때 private은 해당 클래스에서만, public으로 하면 전역적으로 해당 선언된 포인트컷을 사용할 수 있다. 만약 public으로 설정한 포인트컷을 다른 클래스에서 사용할 시에는 선언 타입도 같이 써줘야 한다.(찾지 못함)
@Aspect
@Component
public class AopTest {
//포인트컷 선언
@Pointcut("execution(public void addAccount())")
private void forReUseablility(){}
//선언된 포인트컷 사용
@Before("forReUseablility()")
public void beforeAddAccount() {
log.info("execute addAccount")
}
}
포인트컷 결합 : &&, ||, !을 통해 여러 pointcut을 결합할 수 있다.
@Aspect
@Component
public class AopTest {
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.*(..))")
private void forDaoPackage() {}
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.get*(..))")
private void getter() {}
@Pointcut("execution(* com.luv2code.aopdemo.dao.*.set*(..))")
private void setter() {}
@Pointcut("forDaoPackage() && !(getter() || setter())")
private void forDaoPackageNoGetterSetter() {}
@Before("forDaoPackageNotGetterSetter()")
public void beforeAddAccount() {
log.info("execute addAccount")
}
}
각 메소드에 포인트컷이 적용되는지에 따라 판별하면 될 거 같다. 예를 들어 getter메소드가 있으면 forDaoPackage와 getter는 true이고 setter는 false이다. 따라서 forDaoPackageNotGetterSetter에서는 false의 값이 나오므로 적용되지 않는다.
'Spring Boot > AOP' 카테고리의 다른 글
Spring Boot AOP @Around (0) | 2024.07.31 |
---|---|
Spring Boot AOP 실습3 @AfterThrowing, @After (0) | 2024.07.31 |
Spring Boot AOP 실습3 JoinPoint, @AfterReturning (0) | 2024.07.30 |
Spring Boot AOP 실습2 - @Order (0) | 2024.07.30 |
Spring Boot AOP 개념 (0) | 2024.07.30 |