OOP만으로는 횡단 관심사의 코드분리가 어려웠다. 따라서 OOP의 한계를 해결하기 위해,
비즈니스 로직과 부가적인 로직을 관점(사용자, 개발자)에 따라 모듈화하는 AOP가 등장하게 된 것이다.
기능 | 내용 |
---|---|
핵심기능(Core Concerns) | 객체가 제공하는 고유의 기능(업무 로직 등) |
---------- | ---------- |
부가기능(CROSS-CUTTING CONCERNS) | - 핵심기능을 보조하기 위한 기능 |
- 로그 추적 로직, 보안, 트랜잭션 기능 | |
- 단독사용x, 핵심 기능과 함께 사용 |
함수의 호출 방식은 이렇다.
과거에는 핵심기능(Core Concern)에 부가기능(CROSS-CUTTING CONCERNS)을 직접 넣고 주석처리를 하며 사용하였지만,
AOP는 클라이언트가 요청을 해오면 프락시(Proxy,중개인)를 통해 부가기능(CROSS-CUTTING CONCERNS)이 실행되고 cross-cutting이 핵심기능(core concern)을 호출하게된다. coreConcern의 코드가 끝난 뒤 부가기능이 있다면 실행, 없다면 실행을 마무리한다.
따라서 흐름상으로 볼 때는 핵심기능(coreConcern)과 부가기능(cross-cutting)의 로직이 분리되어 있음에도 이전의 OOP방식이었던 주석처리를 통한 코드구현과 같은형태(코드의 실행순서가 위에서 아래로 흐르는 형태)로 코드가 실행된다.
부가기능을 재사용 하기 위해서는 다음과 같은 의문점이 생긴다.
❓ 어떤 부가기능을? 언제? 어디에 재사용해야 할까?
Advice란, 어떤 부가기능을 언제 사용할지에 대한 정의이다.
- Advice는 기본적으로 순서를 보장하지 않는다. 따라서 순서를 지정하고 싶다면 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 애너테이션을 적용해야한다.
- Aspect를 별도의 클래스로 분리하여 어드바이스 단위가 아닌 클래스 단위로 적용할 수 있다.
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
💡 JoinPoint
명칭 | 개념 | 설명 |
---|---|---|
JoinPoint | 어드바이스가 적용될 수 있는 위치 | 애플리케이션 실행 흐름에서의 특정 포인트를 의미함 |
기본적으로 어드바이스 메소드에 매개변수로 선언하여 사용한다. |
Join포인트가 적용되는 4가지 위치이다.
- 메서드를 호출할 때
- 변수에 접근할 때
- 객체를 초기화할 때
- 객체에 접근할 때
하지만 스프링에서는 메서드를 호출할 때만 JoinPoint라고 한다. 왜냐하면 스프링 AOP는 프록시 방식을 사용하기때문에 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있다. 따라서 조인포인트는 항상 메소드 실행지점으로 제한된다.
JoinPoint 인터페이스 메서드 | 기능설명 |
---|---|
JoinPoint.getArgs() | JoinPoint에 전달된 인자를 배열로 반환합니다. |
JoinPoint.getThis() | AOP 프록시 객체를 반환합니다. |
JoinPoint.getTarget() | AOP가 적용된 대상 객체를 반환합니다. |
클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체를 반환합니다. | |
JoinPoint.getSignature() | 조언되는 메서드에 대한 설명을 반환합니다. |
클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체를 반환합니다 | |
Signature? 객체가 선언하는 모든 연산은 연산의 이름, 매개변수로 받아들이는 객체들을 시그니처라고 합니다. | |
Signature가 제공하는 메서드? String getName() : 클라이언트가 호출한 메소드의 이름을 반환합니다. String toLongString() : 클라리언트가 호출한 메소드의 리턴타입, 이름, 매개변수를 패키지 경로까지 포함해서 반환합니다. String toShortString() : 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 반환합니다. | |
JoinPoint.toString() | 조언되는 방법에 대한 유용한 설명을 인쇄합니다. |
💡 Pointcut
명칭 | 개념 | 설명 |
---|---|---|
Pointcut | 조인 포인트 중에서 Advice를 적용할 위치를 선별하는 기능 | 부가기능을 사용하고자 하는 메서드 실행지점만 포인트컷으로 선별가능하다. |
원하는 곳에만 부가기능을 정의하고자 할 때 Pointcut을 사용한다.
💡 Target
명칭 | 개념 | 사용위치 |
---|---|---|
Target | 부가기능이 적용될 모듈 | 부가기능을 부여할 핵심기능을 담고있는 모듈이다. |