AOP이란? Aspect Oriented Programming : 관점 지향 프로그래밍
하나의 프로그램을 관점(관심사)라는 논리적인 단위로 분리하여 관리하는 개념이다. 여기에서 관심사란 메소드 호출이나 특정주소를 요청하는 등의 행위들을 말한다. 로깅, 감사, 선언적 트렌젝션, 보안, 캐싱 등 다양한 곳에서 사용이 된다.
AOP는 원래 실행되는 코드는 건드리지 않고 AOP를 사용함으로써 모듈을 삽입,호출하는 것에 의의가 있다.
왼쪽의 메소드 호출이라고 되어있는 부분이 바로 관심사 부분이 되겠다. 메소드 호출하는 행위자체를 관심사로 등록했다면 호출된 메소드의 전, 후로 모듈을 삽입하여 사용하는 것이 기본적인 AOP의 개념이자 동작과정이다.
조금 더 쉽게 생각해보면 특정 메소드를 호출하게 되면 그 호출을 가로채서 다른 메소드를 먼저 호출하거나, 아니면 호출된 메소드 이후에 호출하거나 .. 섞어서 사용할 수 있겠다.
웹 프로젝트에서는 특정 웹 페이지를 요청하였을 때, 로그인 여부를 검사하게 하는 것처럼 요청이 발생할 때마다 공통적으로 처리해야할 것이 있을 경우에 사용할 수 있을 것이다!
AOP에서 사용되는 여러가지 용어에 대해서 알아보자. 위의 AOP 동작과정 그림기반으로 용어를 생각하면 이해가 빠르다.
- Join Point : 모듈이 삽입되어 동작하는 실제 위치이다. 관심사가 메소드 호출이라면 위의 그림에서 왼쪽 메소드 호출 부분이 Join Point가 될 것이다.
- Point Cut : 다양한 Join Point중에서 어떤 것을 사용할 것인지 선택하는 것이다. Advice를 적용할 조인 포인트를 선별하는 작업 또는 그 기능을 위한 모듈을 말한다. 즉, 메소드를 선정하는 기능을 가진것을 의미한다.
- Advice : 타겟에게 제공할 부가기능을 담은 모듈을 말한다. 다시말해, Join Point가 벌어질 때 동작할 코드라고 할 수 있겠다.
- Advisor : Point Cut과 Advice를 가지고 있는 오브젝트이다. 어떤 부가기능(Advice)를 어디에(Point Cut) 전달할 것인가를 알고 있는 모듈이라고 할 수 있다.
- Weaving : Advice를 핵심 로직 코드에 적용하는것을 말한다. 메소드를 호출하는 사건이 벌어졌을 때 메소드 전,후에 코드를 삽입해서 하나의 동작으로 만드는 행위를 말한다.
- Aspect : 한개 또는 그 이상의 Point Cut과 Advice조합으로 만들어진 오브젝트이다. Advisor는 아주 단순한 Aspect라고 볼 수 있다.
실제로 동작하는 메소드(메소드의 호출이 관심사이며 Point Cut으로 인해 Advice가 동작한다는 가정)인 Advice의 종류에 대해서 알아보자.
- before : 타겟 메소드 호출 전에 동작하는 Advice이다.
- after : 예외발생 여부와 관계 없이 타겟 메소드의 동작이 완료되면 동작하는 Advice이다.
- around : 타겟 메소드 호출 전, 후에 동작하는 Advice이다.
- after-returning : 예외 없이 호출된 메소드의 동작이 완료되면 동작하는 Advice이다. 예외가 없어야 동작한다.
- after-throwing : 타겟 메소드 동작 중 예외가 발생하면 동작하는 Advice이다.
지금가지 알아본 AOP의 용어들을 실제로 코드에서 어떻게 사용되는지 알아보자.
우선, AOP사용을 위한 의존성을 추가해주어야 하며 aop네임스페이스도 선언해주어야 한다.
mvnrepository에서 AspectJ Weaver를 검색한 후 maven코드를 복사해준다.
Version관리를 위해 버전을 xml property에 설정해주고 변수로 Version을 설정해주었다.
xml configuration 파일에 위와 같은 네임스페이스를 추가해주었다. xmlns:aop와 xsi:schemaLocation에 aop부분을 추가한다.
AdvisorClass라는 클래스를 위와 같이 정의해준다. Advisor종류에서 살펴보았던 before, after, around를 사용해보겠다. 각각 beforeMethod, afterMethod, aroundMethod라는 이름으로 Advisor를 정의해주었다.
around는 다른 2개와 조금 다르게 생겼다?
around는 ProceedingJoinPoint라는 클래스를 매개변수로 받는다. 예외발생을 하여 thorws Throwable도 해준다.
before과 after는 실행위치가 명확하다. 타겟 메소드의 전과 후.
그런데 around는 전과 후의 경계가 약간 애매하다.. 그래서 타겟 메소드(원래 호출할 메소드)의 위치를 직접 정해준다.
위에서 한것 처럼 pjp.proceed() 하면 원래 메소드가 호출된다.
타겟 메소드가 반환값이 없으면 상관이 없는데 반환값이 있을수도 있겠다. Object 형 변수로 받아서 반환을 해주자.
xml Configuration 파일이다. 방금 설정한 Advice를 담고있는 AdvisorClass를 advisor1이라는 이름의 빈으로 등록해준다.
aop:aspect를 advisor1을 참조하게 설정함으로써 advisor1 애스펙트가 만들어졌고, point1이라는 이름으로 Point Cut한개를 만들어 주었다.
expression은 관심사를 설정한다. 위와같이 execution(* method1())로 설정하면 패키지,클래스와 상관없이 method1이라는 메소드가 실행되는 행위를 관심사로 설정하며 이를 실행하는 것을 포인트 컷으로 설정한다는 의미이다. execution명시자에 대해서는 다음 포스트에서 더 자세하게 설명하겠다.
AdvisorClass에서 정의한 메소드를 aop:before, aop:after, aop:around 를 사용해서 가져온다. point1이라고 설정해주었던 Point Cut을 pointcut-ref를 해서 참고(사용)한다.
타겟메소드는 method1()이다. bean1.method1()을 해줄 때 TestBean1이라는 이름의 빈안에 있는 method1() 메소드를 불러왔다.
'metho1 메소드'라는 문자열을 찍어주는 method1() 메소드 앞뒤로 before, after가 실행됨을 확인할 수 있으며 method1()메소드를 감싸는 around메소드가 출력된것을 확인하였다. 함께 찍어봄으로써 before, after보다 around가 더 타겟메소드와 가깝게 실행된다는것을 알 수 있었다.
이번에는 afterReturning과 afterThorwing 을 알아보자.
AdvisorClass에 위와 같이 메소드 두개를 추가해주었다. afterThrowingMethod는 예외가 발생할 때 동작하는 Advice이기 때문에 매개변수로 Throwable을 받고 예외문을 출력까지 해보겠다.
point2라는 이름의 Point Cut을 한개 더 선언했다. 이번에는 위의 예제와 구분하기 위해서 method2를 만들었고, expression="execution(* method2())"를 선언해줌으로써 관심사를 '패키지와 상관없이 method2()를 호출하는 행위' 로 설정하였다.
aop:after-returning, aop:after-throwing을 선언했다. aop:after-throwing는 예외로 던져주었던 변수 e를 throwing="e"로 선언해주어야 한다.
method2()의 반환값이 int형이기 때문에 다음과 같이 출력해주었다. method2()의 반환값이 오류가 없다면(result=100)
afterReturningMethod메소드가 출력되고,
오류가 있다면(result =10/0)
예외문과 함께 afterThrowingMethod 메소드가 출력된다
'JAVA > Spring' 카테고리의 다른 글
@AspectJ 어노테이션 (0) | 2020.04.17 |
---|---|
execution 명시자 (0) | 2020.04.17 |
@Component 어노테이션 (0) | 2020.04.15 |
JSR-250 어노테이션 (0) | 2020.04.11 |
Annotation을 이용한 빈 설정 (0) | 2020.04.11 |