일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- git
- Heap
- redis
- reactive
- javascript
- spring
- 네트워크
- mongodb
- AWS
- mybatis
- Elk
- cache
- r
- network
- nodejs
- libuv
- HTTP
- VCS
- socket
- effective
- ajax
- Java
- html
- Linux
- github
- NoSQL
- reactor
- Lombok
- Static
- 데이터통신
- Today
- Total
빨간색코딩
Spring AOP (개념, 용어, 원리, 포인트컷 표현식, JoinPoint API) 본문
1. AOP란?
Aspect Oriented Programming 의 약자로 관점지향 프로그래밍이라고 부른다. IoC가 낮은 결합도와 관련된 것이라면 AOP 는 높은 응집도와 관련되어 있다.
서비스들의 비즈니스 메소드들은 복잡한 코드로 구성되어있는데, 그 중 핵심 로직은 얼마안되고 대부분은 트랜잭션, 로깅 처리, 인증과 관련된 코드들이 있을 수 있다. 이럴 때 비핵심이지만 꼭 필요하고, 공통화할 수 있는 부분을 따로 빼서(횡단 분리) 관리하는 것이다.
2. AOP 용어
- 조인포인트(Joinpoint) : 클라이언트가 호출하는 모든 비즈니스 메소드, 조인포인트 중에서 포인트컷되기 때문에 포인트컷의 후보로 생각할 수 있다.
- 포인트컷(Pointcut) : 특정 조건에 의해 필터링된 조인포인트, 수많은 조인포인트 중에 특정 메소드에서만 횡단 공통기능을 수행시키기 위해서 사용한다.
- 표현식 : 리턴타입 패키지경로 클래스명 메소드명(매개변수)
- 어드바이스(Advice) : 횡단 관심에 해당하는 공통 기능의 코드, 독립된 클래스의 메소드로 작성한다.
어드바이스의 동작 시점
동작시점 설명 Before 메소드 실행 전에 동작 After 메소드 실행 후에 동작 After-returning 메소드가 정상적으로 실행된 후에 동작 After-throwing 예외가 발생한 후에 동작 Around 메소드 호출 이전, 이후, 예외발생 등 모든 시점에서 동작
- 위빙(Weaving) : 포인트컷으로 지정한 핵심 관심 메소드가 호출될 때, 어드바이스에 해당하는 횡단 관심 메소드가 삽입되는 과정을 의미한다. 이를 통해 비즈니스 메소드를 수정하지 않고도 횡단 관심에 해당하는 기능을 추가하거나 변경이 가능해진다.
- 애스팩트(Aspect) : 포인트컷과 어드바이스의 결합이다. 어떤 포인트컷 메소드에 대해 어떤 어드바이스 메소드를 실행할지 결정한다.
3. AOP 원리
4. 포인트컷 표현식
포인트컷을 이용하면 어드바이스 메소드가 적용될 비즈니스 메소드를 정확하게 필터링할 수 있다.
4-1. 지시자(PCD, AspectJ pointcut designators)의 종류
몇가지들이 있다. 아래에선 execution 을 사용한 표현식에 대해 알아본다.
- execution : 가장 정교한 포인트컷을 만들수 있다. 리턴타입 패키지경로 클래스명 메소드명(매개변수)
- within : 타입패턴 내에 해당하는 모든 것들을 포인트컷
- bean : bean이름으로 포인트컷
4-2. 리턴타입 지정
표현식 | 설명 |
---|---|
* | 모든 리턴타입 허용 |
void | 리턴타입이 void인 메소드 선택 |
!void | 리턴타입이 void가 아닌 메소드 선택 |
4-3. 패키지 지정
표현식 | 설명 |
---|---|
com.devljh.domain | 정확하게 com.devljh.domain 패키지만 선택 |
com.devljh.domain.. | com.devljh.domain 패키지로 시작하는 모든 패키지 선택 |
4-4. 클래스 지정
표현식 | 설명 |
---|---|
UserBO | 정확하게 UserBO 클래스만 선택 |
*BO | 이름이 BO로 끝나는 클래스만 선택 |
BaseObject+ | 클래스 이름 뒤에 '+'가 붙으면 해당 클래스로부터 파생된 모든 자식 클래스 선택, 인터페이스 이름 뒤에 '+'가 붙으면 해당 인터페이스를 구현한 모든 클래스 선택 |
4-5. 메소드 지정
표현식 | 설명 |
---|---|
*(..) | 모든 메소드 선택 |
update*(..) | 메소드명이 update로 시작하는 모든 메소드 선택 |
4-6. 매개변수 지정
표현식 | 설명 |
---|---|
(..) | 모든 매개변수 |
(*) | 반드시 1개의 매개변수를 가지는 메소드만 선택 |
(com.devljh.domain.user.model.User) | 매개변수로 User를 가지는 메소드만 선택. 꼭 풀패키지명이 있어야함 |
(!com.devljh.domain.user.model.User) | 매개변수로 User를 가지지않는 메소드만 선택 |
(Integer, ..) | 한 개 이상의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택 |
(Integer, *) | 반드시 두 개의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택 |
5. JoinPoint 인터페이스
어드바이스 메소드를 의미있게 구현하려면 클라이언트가 호출한 비즈니스 메소드의 정보가 필요하다. 예를들면 예외가 터졌는데, 예외발생한 메소드의 이름이 뭔지 등을 기록할 필요가 있을 수 있다. 이럴때 JoinPoint 인터페이스가 제공하는 유용한 API들이 있다.
메소드 | 설명 |
---|---|
Signature getSignature() | 클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체 리턴 |
Object getTarget() | 클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체 리턴 |
Object[] getArgs() | 클라이언트가 메소드를 호출할 때 넘겨준 인자 목록을 Object 배열 로 리턴 |
Signature API
메소드 | 설명 |
---|---|
String getName() | 클라이언트가 호출한 메소드 이름 리턴 |
String toLongString() | 클라이언트가 호출한 메소드의 리턴타입, 이름, 매개변수(시그니처)를 패키지 경로까지 포함 하여 리턴 |
String toShortString() | 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 리턴 |
사용법
JoinPoint를 어드바이스 메소드 매개변수로 선언해야한다. 이때 인자는 스프링 컨테이너가 넘겨준다. ex. 메소드명(JoinPoint jp)
이때 Around 어드바이스만 다른 어드바이스와 약간 다른데, ProceedingJoinPoint 객체를 인자로 선언해야한다.(proceed() 등이 추가로 구현되어있음) ProceedingJoinPoint 는 JoinPoint를 상속받는다.