2022-06-21(Section2_Spring 핵심_AOP-2)

이상수·2022년 6월 25일
0

TIL_Spring Base

목록 보기
6/6
  1. 시작하게 된 계기 및 다짐 😮
  • 이번 코드스테이츠의 백엔드 엔지니어링 개발자 부트캠프에 참여하게 되면서 현직개발자 분들의 빠른 성장을 위한 조언 중 자신만의 블로그를 이용하여 배운 것 들을 정리하는게 많은 도움이 된다 하여 시작하게 되었다.

    • 그 날 배웠던 것을 길지 않아도 좋으니 정리하며 복습하는 습관 기르기
    • 주말에 다음주에 배울 내용들을 예습
    • 코딩 문제와 java코드들은 꾸준히 학습
    • 자료구조를 이용한 알고리즘 문제 해결 학습
  1. 학습 목표 😮
목표결과
타입별 Pointcu 표현식, JointPoint 등의 의미 이해O
에너테이션을 이용한 AOP에 대해 이해O
  1. 정리

Pointcut 표현식

1. 포인트컷과 표현식 & 지시자
  - 포인트컷은 어드바이스가 실행되는 시기를 제어
  - AspectJ는 포인트컷을 편하게 표현하기 위한 특별한 표현식을 제공한다.
  - AspectJ : AspectJ pointcut expression
  - [ex. @Pointcut("execution(* hello.aop.order..*(..))")]
 
[예제 Code]
@Pointcut("execution(* transfer(..))")   // 포인트컷 표현식
private void anyOldTransfer() {}          // 포인트컷 서명
 ==> 이를 어드바이스에 적용
   [ex. @Around(anyOldTransfer())]


2. 포인트컷 지시자  
 - 포인트컷 지시자(PCD,Pointcut Designater) : execution같은 표현식
 - execution을 가장 많이 사용하고 나머지는 잘 사용하지 않는다.

 1). execution : 메서드 실행 조인트 포인트를 매칭한다.
                    스프링 AOP에서 가장 많이 사용하며, 기능도 복잡하다.
 2). within : 특정 타입 내의 조인 포인트를 매칭한다.
 3). args : 인자가 주어진 타입의 인스턴스인 조인 포인트
 4). this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트
 5). target : Target 객체(스프링 AOP 프록시가 가르키는 실제 대상)를 대상으로 하는 조인 포인트
 6). @target : 실행 객체의 클래스에 주어진 타입의 애너테이션이 있는 조인 포인트
 7). @within : 주어진 애너테이션이 있는 타입 내 조인 포인트
 8). @annotation : 메서드가 주어진 애너테이션을 가지고 있는 조인 포인트를 매칭
 9). @args : 전달된 실제 인수의 런타임 타입이 주어진 타입의 애너테이션을 갖는 조인 포인트
 10). bean : 스프링 전용 포인트컷 지시자이고 빈의 이름으로 포인트컷을 지정한다.

3. Pointcut 표현식 결합
 - &&, ||, !를 사용하여 결합할 수 있다.
 - 이름으로 pointcut 표현식을 참조 할 수 있음

[예제 Code]

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} // (1)
(1) anyPublicOperation은 메서드 실행 조인 포인트가 공용 메서드의 실행을 나타내는 경우 일치

@Pointcut("within(com.xyz.myapp.trading..*)")
private void inTrading() {} // (2)
(2) inTrading 메서드 실행이 거래 모듈에 있는 경우에 일치

@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} // (3)
(3) tradingOperation은 메서드 실행이 거래 모듈의 공개 메서드를 나타내는 경우 일치


4. 일반적인 pointcut 표현식들

1). 모든 공개 메서드 실행
 - execution(public * *(..))

2). set 다음 이름으로 시작하는 모든 메서드 실행
 - execution(* set*(..))

3). AccountService 인터페이스에 의해 정의된 모든 메소드의 실행
 - execution(* com.xyz.service.AccountService.*(..))

4). service 패키지에 정의된 메서드 실행
 - execution(* com.xyz.service.*.*(..))

5). 서비스 패키지 또는 해당 하위 패키지 중 하나에 정의된 메서드 실행
 - execution(* com.xyz.service..*.*(..))

6). 서비스 패키지 내의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
 - within(com.xyz.service.*)

7). 서비스 패키지 또는 하위 패키지 중 하나 내의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
- within(com.xyz.service..*)

8). AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
- this(com.xyz.service.AccountService)

9). AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
 - target(com.xyz.service.AccountService)

10). 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable과 같은 모든 조인 포인트 (Spring AOP에서만 메소드 실행)
 - args(java.io.Serializable)

11). 대상 객체에 @Transactional 애너테이션이 있는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
 - @target(org.springframework.transaction.annotation.Transactional)

12). 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트 (Spring AOP에서만 메서드 실행)
 - @annotation(org.springframework.transaction.annotation.Transactional)

13). 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트(Spring AOP에서만 메서드 실행)
 - @args(com.xyz.security.Classified)

14). tradeService 라는 이름을 가진 스프링 빈의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
 - bean(tradeService)

15). 와일드 표현식 *Service 라는 이름을 가진 스프링 빈의 모든 조인 포인트
 - bean(*Service)


[extra]

JDK Dynamic Proxy
 - Interface를 기반으로 Proxy를 생성하는 방식
 - 그렇기에 Interface를 강제화 한다는 단점이 있다.

CGLIB Proxy
 - Enhancer를 바탕으로 Proxy를 구현하는 방식이다.
 - Reflection을 사용하지 않고 extends(상속)방식을 이용해서 Proxy할 메서드를 오버라이딩 하는 방식

Reflection API
 - 구체적인 클래스 타입을 알지 못해도 그 클래스의 정보(메서드,타입,변수 등등)에 접근할 수 있게 해주는 API
 - [참조] https://tecoble.techcourse.co.kr/post/2020-07-16-reflection-api/






JointPoint

1. AOP 적용 위치
 - 메서드 실행 위치 외 다양한 위치에 적용가능
 - 조인포인트 : 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
 - AOP를 수행하는 메소드는 이 JoinPoint 인스턴스를 인자로 받게됨
 - JoinPoint 인스턴스에서 조인 포인트 지점의 정보를 얻어내야 함

2. JoinPoint 
 - 어드바이스가적용될 수 있는 위치 같은 프로그램 실행 중 지점을 나타냄
 - AspectJ를 사용해서 컴파일 시점/클래스 로딩 시점에 적용하는 AOP는 바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용 가능
 - 프록시 방식을 사용하는 Spring AOP는 메서드 실행 지점만 (조인포인트로 적용가능)AOP 적용가능
 - [프록시는 메서드 오버라이딩 개념으로 동작]
 - 생성자, static 메서드, 필드값 접근 에는 프록시 개념이 적용될 수 없음
 - 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용가능
 - JoinPoint메소드는 기본적으로 어드바이스 매개변수로 선언하면 된다.


3. JoinPoint 인터페이스의 주요 기능

 - JoinPoint.getArgs() : JoinPoint에 전달된 인자를 배열로 반환합니다.
 - JoinPoint.getThis() : AOP 프록시 객체를 반환합니다.
 - JoinPoint.getTarget() : AOP가 적용된 대상 객체를 반환합니다.
     [클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체를 반환합니다.]
 - JoinPoint.getSignature() : 조언되는 메서드에 대한 설명을 반환합니다.
    1). 클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체를 반환합니다
    2). Signature  
        [ 객체가 선언하는 모든 연산은 연산의 이름, 매개변수로 받아들이는 객체들을 시그니처라고 합니다.]
    3). Signature가 제공하는 메서드
         String getName() : 클라이언트가 호출한 메소드의 이름을 반환합니다.
         String toLongString() : 클라리언트가 호출한 메소드의 리턴타입, 이름, 매개변수를 패키지 경로까지 포함해서 반환합니다.
         String toShortString() : 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 반환합니다.
 - JoinPoint.toString() : 조언되는 방법에 대한 유용한 설명을 인쇄합니다.


4). ProceedingJoinPoint 인터페이스의 주요 기능
 - proceed() : 다음 어드바이스나 타켓을 호출합니다.






에너테이션(Annotation)을 이용한 AOP

 ★ 스키마 기반 접근, @AspectJ 에너테이션 스타일

1. @AspectJ 지원
 - 에너테이션이 있는 일반 Java클래스로 관점을 선언하는 스타일
 - Spring은 pointcut 구문 분석 및 일치를 위해 AspectJ제공 라이브러리를 사용하여 AspectJ 5와 동일한 에너테이션을 해석한다.
 - AOP 런타임은 여전히 순수한 스프링 AOP이며, AspectJ 컴파일러나 위버에 의존X

2. AspectJ 지원 활성화
 - Spring에서 @AspectJ를 사용하기 위해 AOP설정과 이런 aspect에 의해 조인되는 자동 프록시 빈에 대한 Spring 지원을 활성화 해야됨
 - XML or JAVA스타일 설정으로 활성화 가능

[예제 Java_Code]
@Configuration
@EnableAspectAutoProxy
public class AppConfig{

}

3. Aspect 선언
 - @AspectJ 지원이 활성화되면 @AspectJ 관점(@Aspect 애너테이션이 있음)이 있는 클래스로 애플리케이션 컨텍스트에 정의된 모든 빈이 Spring에서 자동으로 감지되고 Spring AOP를 구성하는 데 사용됩니다.

[예제 Code]
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}

4. 포인트컷 선언
 - 조인 포인트를 결정하므로, 어드바이스가 실행되는 시기를 제어할 수 있음
 - Spring AOP는 Spring Bean에 대한 메소드 실행 조인 포인트만 지원이 되어 Pointcut은 Spring Bean의 메소드 실행과 일치하는 것으로 생각
 - pointcut 선언은 이름/매개변수를 포함하는 서명과 우리가 관심 있는 메소드 실행을 결정하는 pointcut표현식 두 부분으로 구성
 - pointcut 표현식은 @Pointcut 어노테이션을 사용하여 표시

5. 어드바이스 선언
 - 어드바이스는 포인트컷 표현식과 연관되며 포인트컷과 일치하는 메서드 실행 전후 또는 전후에 실행 됩니다.
 - pointcut 표현식은 pointcut에 대한 단순참조 or 제자리에 선언된 pointcut 표현식일 수 있다.






  1. 피드백 😮
  • 실제 Spring에서 AOP(Aspect)가 적용될 수 있는 JointPoint들과 이를 어디에 적용하는지 선택하는 Pointcut을 이용하여 원하는 곳에 Aspect를 적용하는 방법을 알아보았다.

  • 추가로 advice에는 포인트컷을 적용하는 메서드에서 이를 적용할 시점을 추가적으로 선택하여 적용 할 수 있다.

  • 해당 메서드들과 애너테이션들을 실제 적용시키면서 이를 어떤식으로 사용해야할지 익숙해지고 코드들 자체도 외우기보다는 익숙해져야 할 것 같다.

  1. 앞으로 해야 될 것 😮
  • 매일 꾸준히 할 것
    • 꾸준히 velog 작성
    • Java 언어 및 Algorithm 공부(Coding-Test)
    • 틈틈히 운동 하기

  • 내일 해야 할 것
    • Spring MVC 계층의 API계층을 학습
    • Spring MVC란 무엇이고, 각 M,V,C에 대한 이해
profile
Will be great Backend-developer

0개의 댓글