[데브코스] Spring AOP
Updated: Categories: TILW4D5 Part1 - Spring AOP 개념과 사용법에 대해 공부하자
AOP(Aspect Orient Programming)
- 관점 지향 프로그래밍.
- OOP를 대신하는 개념이 아닌, OOP를 더욱 잘 활용하게 해주는 개념이다.
- 핵심기능과 부가기능을 분리하여 관리하는 것.
기본 구조
(Cross Cutting) Concerns
: 기능이 중복되는 부분이다. 이 부분을Aspect
로 만들어 주는 것이 바로 AOP!
Aspect
: 기존 뜻은 ‘관점’이지만 -> ‘기능’을 묶는 모듈이라고 생각하면 좋다Advice
: 기존 Concern을 Aspect 모듈에 넣으면 Advice.Target
: 핵심 기능을 담고 있는 모듈. 부가기능을 부여할 대상 -> 즉 적용대상 클래스/메소드임PointCut
: Advice를 적용할 Target의 메소드를 선별하는정규표현식
Join point
: Advice가 Target에 적용되는 시점을 뜻한다
AOP 적용 - Weaving
- 컴파일 시점 :
AspectJ
같은 프레임워크를 사용해 컴파일 전 소스코드를 삽입하는 방식 - 클래스 로딩 시점 : 클래스 로딩시 Byte Code를 삽입
- 런타임 시점 : 스프링에서 사용하는 방식으로
Proxy
객체를 활용한다 더 알아보자!
Advice Join Point 분류
JDK dynamic Proxy
??
Spring AOP
- aspectJ 어노테이션을 사용하나, 런타임 시점에서 적용됨
설정
- 우선
pom.xml
에 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Aspect 클래스 생성
@Aspect
어노테이션을 달아줌- 반드시 Bean으로 등록되어야함.
@Aspect
@Component
public class 클래스 {
...
}
PointCut 설정
- 정규표현식으로
Advice
가 적용될 범위인PointCut
을 설정한다 - 정규표현식에 와일드카드로
*
을 사용하고, 경로/인자값타입 생략은..
으로 한다 - Spring AOP는 public만 설정가능…
@Around("execution([접근지정자] [리턴타입] [패키지].[클래스].[메소드]([인자값타입]))")
PointCut 설정 - 메소드 분리
@PointCut
을 사용해 정규표현식을 메소드로 분리하여 미리 정의할 수 있다.- 분리 메소드들은 하나의 클래스에 모아놓으면 깔끔하겠쥬?
// ex) public의 모든 리턴타입을 포함하는
// ~kdt 패키지 하위의 Service 이름이 붙은 모든 클래스가 가지는
// 인자값은 상관없는 모든 메소드
@PointCut("execution(public * org.prgrms.kdt..*Service.*(..))")
public void servicePublicMethodPointCut(){};
// 미리 정의된 PointCut 메소드 사용
@Around("servicePublicMethodPointCut()")
... Advice ...
PointCut 설정 - 어노테이션 분리
- PointCut을 경로로 설정하지 않고 특정 어노테이션으로 설정할 수 있다.
- 해당 어노테이션이 붙은 메소드만이
Target
으로 선정됨
// 어노테이션 만들기
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface 어노테이션명 {
}
@Around("@annotation(~패키지경로.어노테이션명)")
... Advice ...
Advice 설정
- 위에서
PointCut
범위 내의 모든Target
들에게 적용될Advice
로직을 써준다 joinPoint.proceed()
는Target
의 리턴값이 됨
@Around(정규표현식)
public Object 메소드명(ProceedingJoinPoint joinPoint) throws Throwable {
var result = joinPoint.proceed();
return result;
}
- 이제
Target
으로 선정된 메소드가 실행될때마다 위에서 정의한Advice
로직이 실행된다. - 단
Bean
으로 등록된 객체만이Target
으로 지정된다