HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
✍🏻
Learnary (learn - diary)
/
🕞
[Core] - AOP(Aspect-Oriented-Programming)
🕞

[Core] - AOP(Aspect-Oriented-Programming)

progress
Done
Tags
Spring
🏗️ Build Up💨WhatAOP란?AOP 도식화 및 용어❓Why✅How📌 REFER

🏗️ Build Up

  • 관점이라는 용어는 개발자들에게 관심사라는 말로 융통된다.
  • 관심사는 개발 시 필요한 고민이나 염두에 두어야 하는 일이라고 할 수 있는데, 코드를 작성하면서 염두에 두어야 하는 일들은 주로 이렇다.
    • 파라미터가 올바르게 들어왔을까?
    • 로그를 적절하게 남기고 있는가?
    • 사용자가 적절한 권한을 가진 사용자인가?
    • 해당 작업에서 발생할 수 있는 모든 예외는 어떻게 처리해야 하는가?
 
Spring Proxy 자료
[Spring AOP] - Proxy

💨What

AOP란?

🌕
실제 핵심로직(core concern)을 수행하면서 발생하는 횡단 관심사(Cross Cutting Concern)를 한데 모아 처리하는 것을 AOP라고 한다.
  • AOP가 추구하는 것은 관심사의 분리이다.
ex) 나눗셈을 구현한다고 하면, 핵심 로직은 두 개의 숫자를 나누는 것이지만, 주변 로직은 0을 나누는 것이 아닌지 등을 체크하는 것이다.
 
실행 방향은 위에서 아래로 그에 따른 주변 로직은 오른쪽에 있는 로그처리, 보안 처리, 트랜잭션 처리 이다.
notion image
 
 

AOP 도식화 및 용어

notion image
notion image
Target
  • Advice가 적용될 객체이며, 개발자가 작성한 비즈니스 로직은 가지는 객체(Service)를 뜻한다.
  • 순수한 비즈니스 로직을 가지고 있고, 어떠한 관심사들과도 관계를 맺지 않는다.
 
Proxy
  • target을 전체적으로 감싸고 있는 존재(껍질)
  • 내부적으로 Target을 호출하지만, 중간에 필요한 관심하들을 거쳐서 Target을 호출하도록 자동 혹은 수동으로 작성된다.
  • proxy 존재는 직접 코드를 통해서 구현하는 경우도 있지만, 스프링 AOP 기능을 이용해서 자동으로 생성되는 auto-proxy를 이용한다.
 
 
PointCut 과 JoinPoint 그리고 weaving
notion image
*위빙이란? 공통코드(advice)를 핵심 로직 코드에 삽입하는 것 (Aspect 클래스에 정의 한 Advice 로직을 타깃에 적용하는 것을 의미)
 
JoinPoint : Advice가 적용될 수 있는 메서드 혹은 위치
  • 대부분 메소드 단위로 지정한다.
 
Pointcut: Advice를 주입시킬 Target을 선정하기 위한 방법
  • Advice를 어떤 JoinPoint에 결합할 것인지를 결정하는 설정
    • execution: 메서드 기준으로 PointCut 설정
    • withIn: 특정 타입(클래스)을 기준으로 설정
    • this: 주어진 인터페이스를 구현한 객체 대상 설정
    • arg: 특정 파라미터를 가지는 대상들만 PointCut 설정
    • annotation: 특정 어노테이션 적용된 대상만
 
Weaving: Advice를 핵심 코드와 연결 및 적용
  • 지정된 객체에 aspect를 적용해 새로운 proxy를 생성하는 과정
  • @Transaction Aop로 예를 들면, A라는 객체에 트랜잭션 aspect가 지정되어 있다면, A라는 객체가 실행되기 전 커넥션을 오픈하고 실행이 끝나면 커넥션을 종료하는 기능 추가된 프록시 객체가 생성된다. 이 프록시 객체가 앞으로 A라는 객체가 호출되는 시점에 사용된다.
 
Aspect와 Advice
 
Aspect: Advice와 함께 공통 코드 또는 관심사라는 용어로 사용
  • Aspect는 관심사 자체를 의미하는 추상명사 이며, 부가 기능을 정의한 Advice와 Advice를 어디에 적용할지를 결정하는 pointcut을 함께 갖는다.
Advice: Aspect를 구현한 코드
Before: Target의 JointPoint를 호출하기 전에 실행되는 코드
AfterReturniung: 모든 실행이 정상적으로 이루어진 후에 동작하는 코드
AfterThrowing: 예외 발생한 뒤 동작하는 코드
AfterAdvice: 정상적으로 실행되거나 예외가 발생했을 때 구분 없이 실행되는 코드
Around: 메서드의 실행 자체를 제어할 수 있는 가장 강력한 코드(직접 대상 메서드 호출하고 결과나 예외처리가 가능하다.)
스프링 3버전 이후 해당 애노테이션으로 모든 설정이 가능해졌다.

❓Why

  • 핵심 비즈니스 로직만을 남겨 가독성을 높이고 코드 중복을 없애기 위해 사용된다.

✅How

 
@Pointcut 사용법
  1. 포인트컷 분리
    1. @Slf4j @Aspect public class AspectV2 { // hello.aop.order 패키지와 하위 패키지 @Pointcut("execution(* hello.aop.order..*(..))") // pointcut expression private void allOrder() { // -> around로 들어감 } // pointcut signature @Around("allOrder()") public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); return joinPoint.proceed(); } }
  1. 포인트컷 혼합(advice 추가)
    1. @Slf4j @Aspect public class AspectV3 { // hello.aop.order 패키지와 하위 패키지 @Pointcut("execution(* hello.aop.order..*(..))") public void allOrder() { } // 클래스 이름 패턴이 *Service @Pointcut("execution(* *..*Service.*(..))") private void allService() { } @Around("allOrder()") public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); return joinPoint.proceed(); } // hello.aop.order 패키지와 하위 패키지 이면서 클래스 이름 패턴이 *Service @Around("allOrder() && allService()") public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable { try { log.info("[트랜잭션 시작] {}", joinPoint.getSignature()); Object result = joinPoint.proceed(); log.info("[트랜잭션 커밋] {}", joinPoint.getSignature()); return result; } catch (Exception e) { log.info("[트랜잭션 롤백] {}", joinPoint.getSignature()); throw e; } finally { log.info("[리소스 릴리즈] {}", joinPoint.getSignature()); } } }
      @Around("allOrder() && allService()")
      • 포인트컷은 이렇게 조합할 수 있다. && (AND), || (OR), ! (NOT) 3가지 조합이 가능하다.
      • hello.aop.order 패키지와 하위 패키지 이면서 타입 이름 패턴이 *Service 인 것을 대상으로 한다.
      • 결과적으로 doTransaction() 어드바이스는 OrderService 에만 적용된다.
      • doLog() 어드바이스는 OrderService , OrderRepository 에 모두 적용된다.
 
@Around 사용법
// 특정 어노테이션이 명시된 모든 메써드의 실행 전후로 끼어들 수 있다. @Around("@annotation(sampleAnnotation)") public Object somethingAround(final ProceedingJoinPoint joinPoint, final SomeAnnotation someAnnotation) { // 실행 전 Object result = joinPoint.proceed(); // 실행 후 return result; } // 특정 어노테이션이 설정된 모든 method 실행 앞/뒤 @Around("@annotation(scheduled)") public Object process(final ProceedingJoinPoint joinPoint, final Scheduled scheduled) throws Throwable { } // 클래스 레벨에 특정 어노테이션이 명시된 모든 method @Around("@within(org.springframework.web.bind.annotation.RestController) || @within(org.springframework.stereotype.Service) || @within(org.springframework.stereotype.Repository)") public Object process(final ProceedingJoinPoint joinPoint) throws Throwable { }
 
 
왜? Around만 쓰지 다른것은 왜쓰는가?
  • Around는 ProceedingJoinPoint joinPoint를 매개변수로 받고 다른 것들은 JoinPoint joinPoint 를 매개변수로 받는 것에 차이를 시작으로 ProceedingJoinPoint.proceed()를 호출하지 않으면 target에 도달하지 않는 버그 발생의 위험이 있다.
  • 이에반해 다른 것들은 proceed()를 호출하지 않아도 되며 이름만으로도 어떤 AOP인지 바로 확인가능하다는 점에서 같이 사용되고 있다.
 

📌 REFER

 
[Spring] AOP (Aspect-Oriented-Programming)
관점(Aspect)라는 용어는 개발자들에게 관심사(concern)이라는 말로 용통된다. 관심사는 개발 시 필요한 고민이나 염두에 두어야 하는 일이라고 생각할 수 있는데, 코드를 작성하면서 염두에 두어야 하는 일들은 주로 아래와 같다. 파라미터가 올바르게 들어왔을까? 로그는 적절하게 남기고 있는가? 이 작업을 하는 사용자가 적절한 권한을 가진 사용자인가? 이 작업에서 발생할 수 있는 모든 예외는 어떻게 처리해야 하는가?
https://wonyong-jang.github.io/spring/2020/06/02/Spring-AOP.html
[Spring] AOP (Aspect-Oriented-Programming)
[스프링 핵심 원리 - 고급편] 10. 스프링 AOP 구현
프로젝트 생성 이번에는 스프링 웹 기술은 사용하지 않는다. Lombok만 추가하면 된다. 참고로 스프링 프레임워크의 핵심 모듈들은 별도의 설정이 없어도 자동으로 추가된다. 추가로 AOP 기능을 사용하기 위해서 다음을 build.gradle 에 직접 추가하자 주의 build.gradle implementation 'org.springframework.boot:spring-boot-starter-aop' build.gradle 에 테스트 코드에서도 lombok을 사용할 수 있도록 다음 코드를 추가하자 //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' 참고 @A..
[스프링 핵심 원리 - 고급편] 10. 스프링 AOP 구현
https://drow724.tistory.com/m/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B3%A0%EA%B8%89%ED%8E%B8-09-%EC%8A%A4%ED%94%84%EB%A7%81-AOP-%EA%B5%AC%ED%98%84
[스프링 핵심 원리 - 고급편] 10. 스프링 AOP 구현
 
  • expression 의 설명 조금
Spring AOP @Before, @After, @Around
개발을 하다보면 특정 패턴을 가진 메소드에 대해서 공통적으로 적용해줘야하는 기능이 있다. 제일 대표적인게 바로 로그 기록이 있는데, 이와 같은 기능을 특정 패턴을 가진 메소드에 넣기 위해서는 로그를 기록하는 공통 Util 메소드를 생성하고 해당 Util 메소드를 특정 패턴을 가진 메소드에 일일이 넣는 것을 생각할 수 있다. 하지만 이렇게 수동으로 공통 기능을 넣어줄 경우 추후 코드를 수정할 곳이 많아진다거나 어디에 Util 메소드를 넣었는지 찾기가 힘들어 유지보수가 힘들어진다. 위와 같이 특정 패턴을 가진 메소드에 공통되는 위치(실행 전, 실행 후)에 있는 공통되는 기능을 횡단 관심사라고 한다. 그리고 이러한 횡단 관심사를 수동으로 구현할 필요 없이 알아서 지정한 패턴에 넣어주는 방법으로는 Spring ..
Spring AOP @Before, @After, @Around
https://pamyferret.tistory.com/51
Spring AOP @Before, @After, @Around