AOP
AOP( Aspect-Oriented Programming)
관점 지향 프로그래밍
다수의 모듈에 공통적으로 나타나는 부분이 존재하는데 이를 횡단 관심사(cross-cutting concern)라고 한다.
개발자들은 중복 코드를 싫어하기 때문에 이런 횡단 관심사는 단 한 번만 작성하고 싶다.
그때 AOP를 사용한다.
@Aspect
public class MyAspect {
@Before("execution(public void aop002.Boy.runSomething ())")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
}
@Aspect 어노테이션은 이 클래스를 AOP에서 사용하겠다는 뜻
@Before 어노테이션은 대상 메서드 실행 전에 이 메서드를 실행하겠다는 의미다.
중요한 것은 아래 세 개다.
- 스프링 AOP는 인터페이스 기반이다.
- 스프링 AOP는 프록시 기반이다.
- 스프링 AOP는 런타임 기반이다.
예시에서는 @Before을 사용했지만 프록시가 개입할 수 있는 시점은 5가지이다.
- Arround
- Before
- After
- AfterReturning
- AfterThrowing
용어
Pointcut
- Aspect 적용 위치 지정자 : public void aop002.Person.runSomething()
- 여기서는 정규식과 AspectJ 표현식 등을 사용할 수 있다.
- [접근제한자패턴] 리턴타입패턴 [패키지&클래스패턴] 매서드이름패턴(파라미터패턴) [throws 예외패턴]
- [] 대괄호는 생략이 가능하다.
@Aspect
public class MyAspect {
@Before("execution(* runSometing())")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
}
*표시는 와일드 카드로 어떤 클래스의 runSometime 메서드이든 주입할 수 있다.
@Aspect
public class MyAspect {
@Before("execution(* aop002.*")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
}
@Aspect
public class MyAspect {
@Before("execution(* aop002..")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
}
*은 패키지 하위를 나타낼 때도 찍을 수 있으며 * aop002.*는 패키지의 모든 클래스에 적용함을 나타낸다.
비슷하게 ..는 * aop002..와 같이 사용하며 모든 하위 패키지의 모든 클래스에 적용한다.
@Aspect
public class MyAspect {
@Before("execution(* run*")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
}
메서드 이름에도 적용 가능하다.
run으로 시작하는 메서드에 적용하겠다는 뜻이다.
@Pointcut("execution(* aop002.Boy.*(..))")
private void boy() {}
@Before("boy()")
public void before(JoinPoint joinPoint) {
System.out.println("얼굴 인식 확인: 문을 개방하라");
}
이렇게 포인트컷을 미리 만들어두고 사용할 수도 있다.
마지막으로 파라미터 패턴도 존재한다.
- () - 인수 없음
- (*) - 인수 1개 (타입 상관없음)
- (..) - 인수 0~N개 (타입 상관없음)
따라서 위의 예시는 인수가 0개거나 N개인 메서드에 적용하겠다는 것을 나타낸다.
JoinPoint
- 연결점 : JoinPoint joinPoint
- Aspect 적용이 가능한 모든 지점. 이 중 Pointcut에만 적용하는 것이니 Pointcut은 JoinPoint의 부분집합인 셈이다.
- 스프링 AOP에서는 스프링 프레임워크가 관리하는 빈의 모든 메서드에 해당한다.
- Pointcut의 메서드가 호출되면 JointPoint에 그 메서드가 들어올 것이다.
Advice
- 언제 무엇을 : @Before() public void before(JoinPoint joinPoint) { System.out.println("...");}
- pointcut에 적용할 로직과 적용 시점
동작 원리
Spring이 프록시객체를 중간에 삽입해준다.
DispatcherServlet 과 ProductController 입장에서는 변화가 전혀 없다.
- 호출되는 함수의 input, output 이 완전 동일.
- "joinPoint.proceed()" 에 의해서 원래 호출하려고 했던 함수, 인수(argument) 가 전달됨.
- → createProduct(requestDto);
'Spring' 카테고리의 다른 글
[Spring] 🙉Fixture Monkey🙉 (1) | 2024.06.15 |
---|---|
[Spring] DB 테스트 환경 분리 (0) | 2024.06.13 |
[Spring] JUnit 5 단위 테스트 (0) | 2024.06.11 |
[Spring] Naver, Google 로그인 (OAuth2) (0) | 2024.06.10 |
[Spring] Naver 로그인 (Oauth2 X) (1) | 2024.06.08 |