[Spring]AOP

내용
advise
AOP
진행일시
2021/03/18
속성

1.AOP란 ?

관점지향 프로그래밍의 약자이며 중복되는코드 부분을 별도의 영역을 분리해낸다. 이 결과 소스코드의 중복을 줄이고 필요할때마다가 가져다 쓸수 있게 객체화 하는 기술을 말한다.
공통되는 부분을 따로 빼내어 필요한 시점에 해당 코드를 추가한다

1-1 AOP의 장점

1.
공통 관심 사항을 핵심관심사항으로부터 분리시켜 핵심 로직을 깔끔하게 유지할 수 있음
2.
그에 따라 코드의 가독성, 유지보수성을 높일 수 있다.
3.
각각의 모듈에 수정이 필요하면 다른모듈의 수정없이 해당 로직만 변경가능
4.
공통 로직을 적용할 대상을 선택 할 수 있음

2. Spring AOP의 구조

Client: 객체를 호출하는 다른 클래스를 의미
Client가 TargetObject를 호출할 때 중간시점을 가로침 (AOP Proxy의역할)
AOP Proxy : B에 호출당함을 대신해주고 B에해당하는내용을 다못하면 B에게 호출
횡단관점 : 공통적인 코드부분( = advice)
advice들이 합류해야하는 그 시점이 joinPoint == tagetObject에 메소드
advice를 AOP proxy에 끼워서 실행하는 부분을 Weaving이라고한다.
리턴받을 때도 동일 Proxy가 A에게 리턴해줌

ASPECT란?

Proxty가 가로채서 TargetObject를 호출하는 하나의 메소드를 JoinPoint라고한다.
PointCut = joinpoint들의 집합들을 pointCut이라고한다.
Aspect= jdbcTemplate이라고 생각하자

3. Spring AOP의 핵심용어

4. AOP구조 정리

5. Spring AOP 특징

intercept는 spring에서컨테이너를 관리하여 bean을 쓸수있다
filter는 servlet에서 공통적인부분을 처리하는데 사용하여 filter에서는 bean을 쓸수없다

6. advice의 종류

7. JoinPoint 인터스페이스

ㅁ 그 밖에 메소드

/* 메소드 종류 * 1. getKind() : 어떤 종류의 JoinPoint인지 문자열로 반환, 보통은 메소드 호출이므로 "method-execution" * 2. getName() : 클라이언트가 호출한 메소드 이름 리턴 * 3 .toLongString() : 클라이언트가 호출한 메소드의 리턴타입, 이름, 매개변수를 패키지 경로까지 포함해서 리턴 * 4. toShortString() : 클라이언트가 호출한 메소드의 시그니처를 축약한 문자열로 리턴 * 5. getDeclaringType() : JointPoint를 선언하고 있는 타입을 반환한다. 즉, JoinPoint가 메소드이면, 해당 메소드의 클래스를 반환한다. * 6. getDeclaringTypeName() : JoinPoint를 선언하고 있는 타입의 이름을 반환한다. 즉, JoinPoint가 메소드이면, 해당 메소드의 클래스 이름을 반환한다. * */
Java
복사

8. XML에서 사용법

9. Advice를 정의하는 태그

10. @Pointcut 어노테이션 주요 표현식

AOP 사용해보기

@Aspect @Component @Log4j2 public class ExecutionTimeAop { // 모든 패키지 내의 controller package에 존재하는 클래스 @Around("execution(* *..controller.*.*(..))") public Object calculateExecutionTime(ProceedingJoinPoint pjp) throws Throwable { // 해당 클래스 처리 전의 시간 StopWatch sw = new StopWatch(); sw.start(); // 해당 클래스의 메소드 실행 Object result = pjp.proceed(); // 해당 클래스 처리 후의 시간 sw.stop(); long executionTime = sw.getTotalTimeMillis(); String className = pjp.getTarget().getClass().getName(); String methodName = pjp.getSignature().getName(); String task = className + "." + methodName; log.debug("[ExecutionTime] " + task + "-->" + executionTime + "(ms)"); return result; } } 출처: https://mangkyu.tistory.com/121 [MangKyu's Diary]
Java
복사
우선 Aop 클래스로 설정하기 위해 @Aspect 어노테이션을 추가해주었으며, Spring의 빈으로 등록하기 위해 @Component 어노테이션을 추가해주었다. 그리고 우리가 하고자 하는 것은 모든 API의 실행 시간을 측정해주는 것이므로, @Around 어노테이션을 통해 controller 패키지에 존재하는 모든 클래스에 대해 해당 AOP를 적용하겠다고 설정해주었다. 그리고 실행 시간 측정을 위해 StopWatch를 생성하여 측정을 시작하였다 그리고 pjp의 proceed를 통해 실제 핵심 로직을 실행하여 Object 클래스로 결과를 받았다. 이후에 StopWatch를 중단하여 실행 시간을 밀리세컨드로 계산하여 로그를 출력하고 함수를 종료시키고 있다. 만약 실행 시간 측정을 밀리세컨드가 아닌 세컨드로 변경한다고 하면 어떻게 해야 할까? AOP를 적용하지 않았다면 관련 로직의 모든 코드를 수정해주어야겠지만, AOP를 적용함으로써 핵심 로직에 대한 수정 없이 이를 처리할 수 있게 되었다. 출처: https://mangkyu.tistory.com/121 [MangKyu's Diary]