Spring - AOP(Aspect-Oriented Programming)

InSeok·2022년 9월 9일
0

TIL

목록 보기
28/51

Spring - AOP(Aspect-Oriented Programming)

목차


  1. Aspect
  2. Advice
  3. Pointcut
  4. JoinPoint

배운 내용


애스펙트(Aspect)

  • 부가 기능을 정의한 코드인 어드바이스(Advice)와 어드바이스를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합쳐 하나의 모듈로 만든것
  • 여러 객체에 공통으로 적용되는 기능
  • AOP는 기존에 사용하던 OOP를 대체하기 위한 것이 아닌 횡단 관심사를 깔끔하게 처리하기 위해 OOP의 부족한 부분을 보조하는 목적으로 개발됨

핵심 기능(Core Concerns)

  • 업무 로직을 포함하는 기능

부가 기능(CROSS-CUTTING CONCERNS)

  • 핵심 기능을 도와주는 부가적인 기능

  • OOP의 모듈화의 핵심 단위는 클래스이고, AOP의 모듈화의 핵심 단위는 관점이다

  • 관심사의 분리는 모듈화의 핵심이다.

**조인 포인트(join point)**

  • 객체 인스턴스화, 메소드 호출 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미 AOP를 적용할 수 있는 모든 지점, 포인트컷 후보
  • 스프링 AOP는 프록시 방식을 사용하므로 조인 포인트는 항상 메소드 실행 지점으로 제한

**어드바이스(Advice)**

  • 조인포인트에서 수행되는 횡단관심에 해당되는 공통 기능의 코드
  • Aspect를 언제 핵심 코드에 적용할지를 정의

**포인트컷(Pointcut)**

  • 조인 포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능
  • AspectJ 표현식을 사용해서 지정
  • 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만 포인트컷으로 선별 가능

**위빙(Weaving)**

  • 포인트컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용하는 것

**AOP 프록시(proxy)**

  • AOP 기능을 구현하기 위해 만든 프록시 객체
  • JDK 동적 프록시 or CGLIB 프록시

**타겟 (Target)**

  • Adivce를 받는 객체이고 포인트컷으로 결정된다.

**어드바이저(Advisor)**

  • 하나의 어드바이스와 하나의 포인트 컷으로 구성
  • 스프링 AOP에서만 사용되는 특별한 용어

**Advice 순서**

  • 어드바이스는 기본적으로 순서를 보장하지 않는다.
  • 순서를 지정하고 싶으면 @Aspect적용 단위로@Order 애너테이션을 적용해야 한다.
    • 어드바이스 단위가 아니라 클래스 단위로 적용가능
    • 하나의 애스펙트에 여러 어드바이스가 존재하면 순서를 보장받을 수 없기 때문에 별도의 클래스로 애스펙트를 분리해야 한다.

**Advice 종류**

**Before**

  • 조인 포인트 실행 이전에 실행
  • Before Advice 구현한 메서드는 일반적으로 리턴타입이 void 이다.

**After returning**

  • 조인 포인트가 정상 완료 후 실행
  • 메서드가 예외 없이 실행된 이후에 공통 기능을 실행

**After throwing**

  • 메서드가 예외를 던지는 경우에 실행

**After (finally)**

  • 조인 포인트의 동작(정상 또는 예외)과는 상관없이 실행
    • 예외 동작의 finally와 비슷
  • 메서드 실행 후 공통 기능을 실행
  • 일반적으로 리소스를 해제하는데 사용

**Around**

  • 메서드 실행 전 & 후, 예외 발생 시점에 공통 기능을 실행
    • 조인 포인트 실행 여부 선택, 반환 값 변환, 예외 변환 등이 가능
  • 어드바이스의 첫 번째 파라미터는 ProceedingJoinPoint를 사용해야 한다.
  • proceed()를 통해 대상을 실행

**Pointcut 표현식**

**포인트컷 지시자**

  • 포인트컷 표현식은 execution 같은 포인트컷 지시자로 시작

**Pointcut 표현식 결합**

  • 포인트컷 표현식은 &&, ||, !를 사용하여 결합 가능
  1. anyPublicOperation은 메서드 실행 조인 포인트가 공용 메서드의 실행을 나타내는 경우 일치합니다.
  2. in Trading 메서드 실행이 거래 모듈에 있는 경우에 일치합니다.
  3. tradingOperation은 메서드 실행이 거래 모듈의 공개 메서드를 나타내는 경우 일치

**일반적인 pointcut 표현식**

  • 모든 공개 메서드 실행
    • execution(public * *(..))
  • set 다음 이름으로 시작하는 모든 메서드 실행
    • execution(* set*(..))
  • AccountService 인터페이스에 의해 정의된 모든 메소드의 실행
    • execution(* com.xyz.service.AccountService.*(..))
  • service 패키지에 정의된 메서드 실행
    • execution(* com.xyz.service.*.*(..))
  • 서비스 패키지 또는 해당 하위 패키지 중 하나에 정의된 메서드 실행
    • execution(* com.xyz.service..*.*(..))
  • 서비스 패키지 내의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • within(com.xyz.service.*)
  • 서비스 패키지 또는 하위 패키지 중 하나 내의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • within(com.xyz.service..*)
  • AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • this(com.xyz.service.AccountService)
  • AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • target(com.xyz.service.AccountService)
  • 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable과 같은 모든 조인 포인트 (Spring AOP에서만 메소드 실행)
    • args(java.io.Serializable)
  • 대상 객체에 @Transactional 애너테이션이 있는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • @target(org.springframework.transaction.annotation.Transactional)
  • 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트 (Spring AOP에서만 메서드 실행)
    • @annotation(org.springframework.transaction.annotation.Transactional)
  • 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트(Spring AOP에서만 메서드 실행)
    • @args(com.xyz.security.Classified)
  • tradeService 라는 이름을 가진 스프링 빈의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
    • bean(tradeService)
  • 와일드 표현식 Service 라는 이름을 가진 스프링 빈의 모든 조인 포인트
    • bean(*Service)

JoinPoint

  • AOP 를 수행하는 메소드는 이 JoinPoint 인스턴스를 인자로 받게 된다.
  • JoinPoint 인스턴스에서 조인 포인트 지점의 정보를 얻어내야 한다.
  • 프록시는 메서드 오버라이딩 개념으로 동작
  • 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용불가
  • 스프링 AOP는 스프링 빈에만 AOP를 적용가능

**JoinPoint 인터페이스의 주요 기능**

  • JoinPoint.getArgs() : JoinPoint에 전달된 인자를 배열로 반환합니다.
  • JoinPoint.getThis() : AOP 프록시 객체를 반환합니다.
  • JoinPoint.getTarget() : AOP가 적용된 대상 객체를 반환합니다.
    • 클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체를 반환합니다.
  • JoinPoint.getSignature() : 조언되는 메서드에 대한 설명을 반환합니다.
    • 클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체를 반환
  • proceed() : 다음 어드바이스나 타켓을 호출

**@AspectJ 지원**

  • @AspectJ는 애너테이션이 있는 일반 Java 클래스로 관점을 선언하는 스타일

활성화

  • 자동 프록시 빈에 대한 Spring 지원을 활성화해야한다.
  • @Configuration으로 @AspectJ 지원을 활성화하려면 @EnableAspectJAutoProxy
    애너테이션을 추가
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

선언

  • @AspectJ 지원이 활성화되면 @AspectJ 관점(@Aspect 애너테이션이 있음)이 있는 클래스로 애플리케이션 컨텍스트에 정의된 모든 빈이 Spring에서 자동으로 감지되고 Spring AOP를 구성하는 데 사용된다.
  • AopUtils.isAopProxy() 를 사용하면 AOP 프록시가 적용 되었는지 확인가능
profile
백엔드 개발자

0개의 댓글