728x90

예제는 깃허브에 있다.

AOP (Aspect Oriented Programming)

AOP는 스프링의 핵심 구성요소중 하나이다.
관점지향 프로그래밍은 프로그램 구조에 대한 또 다른 사고방식을 제공하며
객체 지향 프로그래밍을 보완해준다.

  • OOP의 모듈화 핵심 단위
    • 클래스
  • AOP의 모듈화 단위
    • 관점 (aspect)

AOP는 횡단 관심사의 분리를 허용해주어 모듈성을 높이는 것을 목표로 하는 패러다임이다.
코드 자체를 수정하지 않고 기존 코드에 추가 동작을 추가해서 수행한다.

개념 그리고 용어

  • Aspect
    • 여러 클래스에 중복되어 있는 관심사의 모듈화
    • 대표적인 예로 트랜잭션 관리가 있다.
    • Spring AOP 에서는 @Aspect를 사용한다.
  • JoinPoint
    • 메소드 실행이나 예외 처리와 같은 프로그램 실행중인 지점
    • AOP에서의 JoinPoint는 항상 메소드 실행을 나타냄.
  • Advice
    • 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의
    • around, before, after 등이 있음.
    • AOP 프레임워크는 관점을 인터셉터로 모델링하고 유지한다.
    • 타깃 오브젝트에 종속되지 않는 순수한 부가기능을 담은 오브젝트
  • PointCut
    • Advice가 이 포인트컷 표현식과 연관되고, 일치하는 모든 조인 포인트에서 실행되게 한다.
    • JoinPoint의 상세 스펙을 정의한 것이다.
    • 스프링은 기본적으로 AspectJ의 pointcut 표현식을 사용한다.
  • Advisor
    • PointCutAdvice를 하나씩 가지고 있는 오브젝트
    • 어떤 기능을 어디에 전달할 것인지를 알고있는 가장 기본이 되는 모듈
    • Spring AOP에서만 사용되는 용어

스프링 AOP의 특징

프록시 패턴 기반의 AOP 구현체, 프록시 객체를 사용하는 이유는 여러개의 부가 기능들을 추가하기 위해서 사용한다.
스프링 빈에만 AOP를 적용할 수 있다.
스프링 IoC와 연동해서 중복 코드, 프록시 패턴 구현의 번거로움, 객체간 복잡도 해결을 진행한다.
결국 프록시 패턴, 데코레이터 패턴에 대한 중복도도 제거하려고 나온것이 스프링 AOP라고 생각한다.

스프링 프록시 방식의 AOP 적용

프록시 방식의 AOP를 적용하려면 최소 아래의 네가지 빈을 등록해야 한다.

  • AutoProxyCreator
  • Advice
  • PointCut
  • Advisor

일반 스프링 프레임워크에서는 설정을 해주려면 xml에 여러가지 설정들을 해주어야 하지만,

부트에서는 build.gradle에 의존성 하나만 추가해주면 자동으로 설정이 된다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop
}

추가적으로 PointCut을 정의할 때에는 위에서 설명했던 것 처럼
AspectJ 표현식을 통해 정의해준다. 자세한건 여기를 통해서 확인할 수 있다.

AOP 어노테이션

모든 어노테이션 뒤에는 AspectJ 표현식을 사용해서 적용할 부분을 정의해준다.

  • @Pointcut
    • AspectJ를 적용할 타겟을 정의해준다.
    • 전체 컨트롤러의 함수대상, 특정 어노테이션을 설정한 함수대상, 특정 메소드 대상 등 적용하기를 원하는 범위를 정의하는 어노테이션
  • @Before
    • 조건 표현식에 정의한 메소드들이 실행되기 전에 수행
  • @AfterReturning
    • 적용된 타깃 메소드가 실행된 후에 수행
  • @Around
    • 타깃 메소드 실행 전, 후 처리 둘다 수행이 가능
    • 사용해줄 때 해당 메소드를 ProceedingJoinPoint로 받아준다.

프록시 팩토리의 기술 선택 방법

  • 대상에 인터페이스가 있으면
    • JDK 동적 프록시, 인터페이스 기반 프록시
  • 대상에 인터페이스가 없으면
    • cglib, 구체 클래스 기반 프록시
  • ProxyFactory의 setProxyTargetClass(true);
    • cglib, 구체클래스 기반 프록시, 인터페이스 여부 상관없음
728x90

'Spring' 카테고리의 다른 글

@ModelAttribute, @RequestBody 커맨드 객체  (3) 2022.09.15
@Valid, @Validated 차이  (0) 2022.08.10
@ExceptionHandler  (0) 2022.08.10
Spring Rest Docs 테스트로 문서화를 해보자!  (0) 2022.08.10

+ Recent posts