AOP란? Aspect Oriented Programing(관계 지향 프로그래밍)의 약어이다. AOP는 다음 두가지 요소로 구성된다고 할 수 있다.
1. 중심적 관심사 : 실현해야하는 기능
2. 횡단적 관심사 : 실현하는 프로그램과 별도로 부수적으로 필요한 프로그램
간단하게 설명하자면, 공통 처리 등의 '횡단적 관심사' 를 추출하고 프로그램의 여러 곳에서 호출할 수 있게 설정함으로써 개발자는 실현해야 할 기능인 '중심적 관심사' 에만 집중해서 작성하면 되는 구조이다.
proxy bean 를 이용해서 weaving이 된다.
용어 | 내용 |
---|---|
Advice | 횡단적 관심사의 구현(메소드). 로그 출력 및 트렌잭션 제어 등 |
Aspect | Advice를 정리한 것(클래스) |
JoinPoint | Advice를 중심적인 관심사에 적용하는 타이밍. 메서드(생성자) 실행 전, 메서드(생성자) 실행 후 등 실행되는 타이밍 |
Pointcut | Advice를 삽입할 수 있는 위치 |
Interceptor | 처리의 제어를 인터셉트하기 위한 구조 또는 프로그램. 스프링에서는 인터셉트라는 메커니즘으로 Advice를 중심 관심사에 추가한 것처럼 보이게 함 |
Target | Advice가 도입되는 대상 |
Weaving | 어드바이스를 핵심 로직 코드에 삽입하는 것을 말함 |
어드바이스 | 내용 | 어노테이션 |
---|---|---|
Before Advice | 중심적 관심사가 실행되기 이전에 횡단적 관심사를 실행 | @Before |
After Returning Advice | 중심적 관심사가 정상적으로 종료된 후에 횡단적 관심사를 실행 | @AfterReturning |
After Throwing Advice | 중심적 관심사로부터 예외가 던져진 후에 횡단적 관심사를 실행 | @AfterThrowing |
After Advice | 중심적 관심사의 실행후에 횡단적 관심사를 실행(정상 종료거나 예외 종료 이던 상관 없이) | @After |
Around Advice | 중앙적 관심사 호출 전후에 횡단적 관심사를 실행 | @Around |
와일드카드 | 내용 |
---|---|
*(애스터리스크) | 임의의 문자열을 나타내고, 패키지를 나타낼 때는 임의의 패키지 한 계층을 나타냄. 메서드의 인수에서는 한 개의 인수를 나타내 반환값으로도 이용 가능 |
.. | 패키지를 나타내는 경우 0개 이상의 패키지를 나타냄. 메서드의 인수를 표현하는 경우에는 0개 이상의 임의의 인수를 나타냄. |
+ | 클래스명 뒤에 기술해 클래스와 그 서브클래스 및 구현 클래스 모두를 나타냄. |
ex
execution(* ..LogicInter.(..)) ☞ LogicInter 클래스의 메서드 0개 이상 사용
프록시(Proxy)란? 대리자 라는 뜻으로, 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장해서 클라이언트의 요청을 받아주는 역할을 한다.
프록시는 실제 대상인 것처럼 위장함으로서 이를 사용하는 클라이언트는 구체 클래스를 알 필요가 없어진다.
또한 프록시는 클라이언트의 요청을 받아서 원래 요청 대상에게 바로 넘겨주는 게 아닌, 다양한 부가기능을 지원할 수 있다.
여기서 원래 요청하려는 대상, 즉 최종적으로 요청을 위임받아 처리하는 실제 오브젝트를 타깃이라고 한다.
클라이언트의 요청을 대리로 수행해주는 모든 객체가 프록시 인것은 아니다.
객체가 프록시가 되려면 클라이언트는 요청을 보낸 대상이 타깃인지 프록시인지 구분을 할 수 없어야 한다. 즉, 타깃과 프록시는 같은 인터페이스를 확장해야 한다. 이로써 느슨한 연결을 유지하며, OCP원칙을 통해 좋은 코드를 작성할 수 있다.
소스 코드 - https://github.com/junghyeyoun/spring/tree/main
❗ 앞선 포스팅처럼 MavenProject 사용
✏ https://mvnrepository.com/ 여기서 추가해야할 소스 찾을 수 있음
1️⃣ pom.xml 수정
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.20</version>
</dependency>
aop를 사용하기 위해 위와 같은 내용을 추가해준다.
2️⃣ init.xml 수정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="pack"/>
<aop:aspectj-autoproxy/>
</beans>
장황해 보이지만 결국엔 자신의 패키지이름과 맞게 수정을 해주고 aop를 사용하기 위해 <aop:aspectj-autoproxy/>
를 추가한 것 밖에 없다.
3️⃣ AOP 클래스 생성
package pack;
// import 생략
@Component
@Aspect
public class SampleAspeck {
}
이 클래스는 관심사항을 담은 클래스 즉, Aspect를 담은 Advice라고 할 수 있다.
Advice를 기술하는 클래스는 @Aspect를 부여한다. 따라서 이 클래스에 @Aspect를 부여하였고 인스턴스를 생성하기 위해 @Component 또한 부여하였다.
4️⃣ Advice 활용
Before Advice, After Advice, Around Advice 등을 활용하여 중심적 관심사에 횡단적 관심사를 인터셉트할 수 있다.
참고
스프링 프레임워크 첫걸음- 주식회사 후루네스 키노시타 마사아키 지음 , 전민수 옮김
https://howtodoinjava.com/spring-aop-tutorial/ (aop 이미지)
https://yejun-the-developer.tistory.com/5 (proxy)