1강 - AOP(Aspect Oriented Programming) 이란?
Aspect 의 의미 : "관점" 이라는 뜻.
개발을 하다보니 사용자의 관점만이 아닌 개발자의 관점, 운영자(관리자)의 관점도 존재한다.
AOP란,
사용자의 관점에서 주 업무 로직과 개발자의 관점 또는 운영자의 관점의 보조 업무 로직을
어떻게 분리하고 결합하여 프로그램을 만들 것인가? 에 대한 방법론.
*용어: Primary(Core) Concern 과 Cross-cutting Concern
(주 업무) (보조 업무)
(보조업무는 탈 부착이 가능하다.)
과거에는 Cross-cutting 하는 것이 쉽지 않았다.
주 업무 소스코드에 직접 보조 업무 소스코드가 박혀 있기때문에 소스코드를 직접 손댔어야 했기때문이다.
=> 위와 같은 이유로 수정 후 배포 작업이 매번 번거로웠다.
이러한 단점을 극복하고자 AOP 방법론이 등장하였다.
보조 업무의 Aspect(관점) 코드를 직접 주 업무 소스코드에 꽂아 넣지 않고, 마치 꽂아 넣은 것 처럼 실행 될 수 있도록
하는 방법론이다.
(물리적으로는 따로 분리되어있지만, 논리적으로는 하나로 이루어져있는 것처럼 실행된다.)
2강 - AOP 자바 코드 이해하기
과거 : 주 업무 로직과 보조 업무 로직이 함께 존재
현재 : 주 업무 로직과 보조 업무 로직을 분리해서 처리
[구현 틀]
[구현 예]
위에서 순수 자바로 만든 examProxy(주 업무 + 보조 업무)의 대한 소스 코드를 수정할때 일반적으로 수정이 불편하다.
스프링에서 Proxy의 결합&분리를 Spring DI로 편리하게 해결 가능하다.
3강 - 순수 자바로 AOP 구현해보기
Proxy 는 "가짜" 라는 뜻을 가지고 있다.
Exam의 Proxy를 만들어주는 것이다.
사용자 입장에서는 Exam과 Proxy가 똑같아 보이기 때문에 Exam을 쓰는 것 처럼 느낄 수 있다.
Exam 은 주 업무만 가지고 있고, Proxy 는 주 업무 + 보조 업무 를 둘 다 가지고 있다.
==> Exam(주 업무의 기능만) <=> Proxy(주 업무 + 보조 업무 기능)
따라서 개발자와 운영자는 Proxy를 사용하여 주 업무 기능과 보조 업무 기능을 동시에 사용하고,
사용자에게는 주 업무만 사용하게 Exam을 붙여주면 된다.
프록시 생성하는 기본 틀
Exam proxy = Proxy.newProxyInstance(loader, interfaces, h);
* [매개변수 분석]
loader : 실제 업무 할 수 있게끔 실제의 정보를 갖고 있는 클래스
interfaces : loader(주 업무)의 인터페이스들의 정보를 전달(복수 임으로 배열로 전달)
h : 곁다리 업무를 꽂을 수 있는 부분
위와 같이 Proxy를 만들어 곁다리 업무를 껴 넣으면
System.out.printf("total is %d \n", proxy.total());
System.out.printf("avg is %f \n", proxy.avg());
각각 다른 total() 메서드와 avg() 메서드를 사용할때 Proxy를 활용할 수 있다.
주 업무만 사용하려면 exam 객체를 사용하고,
보조 업무도 같이 사용하고 싶다면 proxy 객체를 사용하면 된다.
4강 - 스프링 AOP로 AroundAdvice 구현하기
스프링이 제공하고 있는 Proxy 클래스를 사용해보자.
=> 1. 주 업무 2. 보조 업무 만든 후 IoC 컨테이너에 담아 두기!!!
*[보조 업무의 유형]
스프링으로 AOP를 구현해 보자!
1. 주 업무를 갖고 있는 NewlecExam 클래스를 bean 등록해준다.
2. 보조 업무의 로직이 정의되어있는 LogAroundAdvice 클래스를 bean 등록해준다.
3. 스프링에서 지원하는 Proxy 생성 클래스를 이용하여 주 업무와 보조 업무를 등록해준다.
5강 - BeforeAdvice 구현하기
6강 - After Returning / Throwing Advice 구현하기
Before Advice 와 After Advice 의 매개변수가 조금 차이가 있다.
매개변수에 주 업무가 끝나고 반환된 값이 들어있다.
=> After Advice는 주 업무가 끝나고 처리되는 보조 업무이기 때문에 주 업무가 실행되고 반환되는 값을
사용할 일이 생기면 사용하라고 매개변수로 같이 넘어온다.
Throwing Advice 는 ThrowsAdvice를 해도 밑줄이 안뜬다.
Why?
==> 어떤 예외처리에 관해서 보조 업무 처리를 해야하는지 모르기 때문이다.
따라서 우리가 예외처리를 하고 싶은 것의 보조 업무 함수를 만들어야한다.
[틀 Ex]
public void afterThrowing(예외종류 e) throws Throwable{
}
[실제 Ex] ArrayIndexOutOfBoundsException 예외처리에 대한 보조 업무 로직을 구현하기.
public void afterThrowing(ArrayIndexOutOfBoundsException e) throws Throwable{
}
3가지 종류를 한번에 종류
==> 다음 시간에는 total() 메서드, avg() 메서드를 모두 실행할때 로그(보조 업무)가 발생하는 것이 아닌
특정 메소드(특정 업무)를 실행할때만 로그(보조 업무)가 실행될 수 있도록 하게 만들어보자!
7강 - Point Cut(Weaving, Join Point)
Proxy를 이용해서 곁다리 업무와 주 업무(target)를 연결하는 것(하얀색 실선)을 위빙(Weaving)이라고 한다.
곁다리 업무가 연결 대상으로 삼고 있는 주 업무(target)를 조인 포인트(Join Point)라고 한다.
이전에는 total() 메서드[join point]와 avg() 메서드[join point]에(모든 주 업무) 위빙(Weaving)이 되어 있었다.
==> 이번 시간에는 total() 메서드에만 위빙을 하는 것을 Pointcuts 이라고 한다.
setting.xml 파일에서
1. 특정 주 업무만 실행할 수 있게 Pointcut을 설정하는 Pointcut bean 등록하기
<bean id="classicPointCut" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedName" value="total" />
</bean>
2. 위에 설정한 Pointcut과 Advice를 연결해주는 설정소스
classicBeforeAdvisor 이라는 bean에서 보조업무 등록하는 setAdvice 와 포인트 컷을 등록하는 setPointcut을 해준다.
==> 따라서 classicBeforeAdvisor은 주 업무 전에 보조 업무가 실행되고, 주 업무는 total()
ex. BeforeAdvice 를 할때 보조업무를 total()만 실행하게 하고 싶다.
<bean id="classicBeforeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<!-- setAdvice()를 말하는 것 -->
<property name="advice" ref="logBeforeAdvice"></property>
<!-- setPointcut()을 말하는 것 -->
<property name="pointcut" ref="classicPointCut"></property>
</bean>
3. 프록시에 위에서 만든 조인 포인트(classicBeforeAdvisor)를 등록해준다.
<bean id="exam" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target" />
<property name="interceptorNames">
<list>
<value>logAroundAdvice</value>
<value>classicBeforeAdvisor</value>
<!-- <value>logBeforeAdvice</value> -->
<value>logAfterReturningAdvice</value>
<value>logAfterThrowingAdvice</value>
</list>
</property>
</bean>
8강 - 간소화된 Advisor
Pointcut을 구현하는데 있어 이전 시간에 너무 복잡하게 만들었다.
Pointcut 기능을 내재하고 있는 Advisor이 있다. [Advice + Pointcut]
ex. total() 메서드만 실행하게 할때
<bean id="classicBeforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- setAdvice()를 말하는것 -->
<property name="advice" ref="logBeforeAdvice" />
<property name="mappedName" value="total" />
</bean>
ex. total() 메서드와 더불어 복수의 메서드만 실행하게 할때 list로 등록
<bean id="classicBeforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- setAdvide()를 말하는것 -->
<property name="advice" ref="logBeforeAdvice" />
<property name="mappedNames" >
<list>
<value>total</value>
<value>avg</value>
</list>
</property>
</bean>
* 이름이 비슷한 패턴의 메소드명을 갖고 있는 메소드를 Pointcut 지정하려면 어떻게 해야할까?
출처: 뉴렉쳐 (https://youtu.be/y2JkXjOocZ4)
'스프링 프레임워크' 카테고리의 다른 글
Spring MVC (스프링 웹 MVC) 14강 ~ 24강 (0) | 2021.03.24 |
---|---|
Spring MVC (스프링 웹 MVC) 1강 ~ 13강 (0) | 2021.03.19 |
뉴렉처[스프링 프레임워크] 16강~17강 (0) | 2021.03.02 |
뉴렉처[스프링 프레임워크] 10강~15강 (0) | 2021.02.25 |
뉴렉처[스프링 프레임워크] 5강~9강 (0) | 2021.02.23 |