Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

Develog

코드스테이츠 38일차 본문

코드스테이츠

코드스테이츠 38일차

안형준 2022. 6. 20. 18:09

학습 목표

  • AOP의 의미를 이해할 수 있다.
  • AOP가 필요한 이유에 대해 이해할 수 있다.
  • AOP에서 사용되는 용어들에 대해 이해할 수 있다.
  • 타입별 Advice, Pointcu 표현식, JointPoint 등의 의미를 이해할 수 있다.
  • 애너테이션을 이용한 AOP에 대해 이해할 수 있다.

 

AOP가 필요한 이유

 먼저 그 전에 객체 지향 프로그래밍(Object Oriented Programming:OOP)에 대해 다시 생각해보자

  • 이전과 현재에 많은 프로젝트는 OOP 패러다임을 지향하며 프로그래밍을 하고 있다.
  • OOP의 핵심은 공통된 목적을 띈 데이터와 동작을 묶어 하나의 객체로 정의하는 것이다.
  • 객체를 적극적으로 활용함으로써 기능을 재사용할 수 있는 것이 큰 장점이다.
  • 객체를 잘 활용하기 위해선 관심사 분리 (Separation of Concerns, SoC)의 디자인 원칙을 준수해야한다.

 

문제점

  • 특정 관심사 업무 코드에 트랜잭션, 보안, 로깅 등의 코드가 존재하게 된다.
  • 트랜잭션, 보안, 로깅 코드는 업무와는 관련이 없지만 애플리케이션에 필수적인 부가 기능이다.
  • 트랜잭션, 보안, 로깅 기능은 불특정 다수의 클래스에서 존재하게 된다.
  • 관심사 관점에서는 트랜잭션, 보안, 로깅 코드들을 횡단 관심사(Cross-cutting Concerns: 부가 기능)라고 한다.
  • 업무 관련 코드는 핵심 관심사(Core Concerns: 핵심 기능)라고 한다.
  • 비즈니스 클래스에 횡단 관심사와 핵심 관심사가 공존하게 된다.

애스펙트(Aspect) 관점은 하나 하나의 기능 → 횡단 관심사(cross-cutting concerns) 관점으로 보는 것이라고 볼 수 있다.

 

AOP의 등장

OOP만 사용해선 횡단 관심사 코드를 깔끔하게 분리하고 비즈니스 코드에 적용하기 어려웠다.

이러한 한계를 해결하고자 AOP가 등장하게 되었다.

 

AOP란?

AOP(Aspect-Oriented Programming)는 기존과 다른 프로그램 구조 사고 방식을 제공함으로써 객체 지향 프로그래밍(OOP)의 부족한 부분을 보완한다.

OOP의 모듈화의 핵심 단위는 클래스이고, AOP의 모듈화의 핵심 단위는 관점이라고 볼 수 있다.

Aspect는 여러 유형과 객체 간에 발생하는 문제 (ex. 트랜잭션)의 모듈화를 가능하게한다.

 

AOP의 핵심 기능과 부가 기능

  • 핵심 기능(Core Concerns)
    • 객체가 제공하는 고유의 기능(업무 로직 등을 포함)
  • 부가 기능(CROSS-CUTTING CONCERNS)
    • 핵심 기능을 보조하기 위해 제공되는 기능이다.
    • 로그 추적 로직, 보안, 트랜잭션 기능 등이 있다.
    • 단독으로 사용되지 않고 핵심 기능과 함께 사용된다.

 

부가 기능은 보통 여러 클래스에 걸쳐서 함께 사용되며, 이러한 기능이 바로 횡단 관심사이다.

  • 부가 기능을 여러 곳에 적용하려면 번거롭고 중복 코드가 생기게 된다.
  • 부가 기능에 수정이 필요하게 되면 사용 되는 클래스에 모두 하나씩 차자가면서 수정해야한다.

 

AOP가 필요한 이유?

소프트웨어 개발에서 변경 지점은 하나가 될 수 있도록 잘 모듈화 되어야 한다.

부가 기능처럼 특정 로직을 애플리케이션 전반에 적용하는 문제는 일반적인 OOP 방식으로는 해결이 어렵기 때문에 핵심 기능과 부가 기능을 분리하는 AOP 방식이 필요한 것이다.

 

총정리

  • 객체 지향 프로그래밍(OOP)는 객체 지향 프로그래밍이다.
  • OOP 방식의 프로그래밍을 했을 때 여러 곳에서 공통적으로 사용되는 부가 기능의 중복 코드가 발생하게 된다.
  • 중복되는 부가 기능에 수정 및 삭제가 필요하게 되면 사용되는 모든 곳에 수정 및 삭제 동작을 해줘야한다.
  • 관심 지향 프로그래밍(AOP)은 OOP 방식의 불필요한 반복을 해결하기 위한 방법이다.

 

AOP 용어

애스팩트(Aspect)

  • 여러 객체에 공통으로 적용되는 기능을 말한다. (공통 기능)
  • 어드바이스 + 포인트컷을 모듈화하여 애플리케이션에 포함되는 횡단 기능이다.
  • 여러 어드바이스와 포인트컷이 함께 존재한다.

 

조인 포인트(join point)

S는 메서드 실행 전의 포인트이고 E는 메서드 수행 후의 포인트이다. 이러한 포인트를 어드바이스가 적용될 조인포인트라고 부른다.

  • 클래스 초기화, 객체 인스턴스화, 메소드 호출, 필드 접근, 예외 발생과 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미한다.
  • 애플리케이션에 새로운 동작을 추가하기 위해 조인포인트에 관심 코드(aspect code)를 추가할 수 있다.
  • 횡단 관심은 조인포인트 전/후에 AOP에 의해 자동으로 추가된다.
  • 추성적인 개념이고 AOP를 적용할 수 있는 모든 지점이라 생각하자
  • 스프링 AOP는 프록시 방식을 사용하므로 조인 포인트는 항상 메소드 실행 지점으로 제한된다.
  • 어드바이스 적용이 필요한 곳은 애플리케이션 내에 메서드를 갖는다.

 

어드바이스(Advice)

  • 조인포인트에서 수행되는 코드를 의미한다.
  • Aspect를 언제 핵심 코드에 적용할 지를 정의한다.
  • 시스템 전체 애스펙트에 API 호출을 제공한다.
  • 위 그림처럼 메소드를 호출하기 전에 각 상세 정보와 모든 메소드를 로그로 남기기 위해 메소드 시작 전의 포인트인 조인포인트 S를 선택한다.
  • 부가 기능에 해당된다.

 

포인트컷(Pointcut)

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

 

위빙(Weaving)

  • 포인트컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용하는 것이다.
  • 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가 할 수 있다.
  • AOP 적용을 위해 애스펙트 객체에 연결한 상태이다.

 

AOP 프록시(proxy)

  • AOP 기능을 구현하기 위해 만든 프록시 객체이다.
  • 스프링에서 AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시이다.

 

타겟 (Target)

  • 핵심 기능을 담고 있는 모듈로 타겟은 부가기능을 부여할 대상이 된다.
  • Adivce를 받는 객체이고 포인트컷으로 결정된다.

 

어드바이저(Advisor)

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

 

어드바이스(Advice)

  • Aspect를 언제 핵심 코드에 적용할지를 정의한다.
  • 부가 기능에 해당된다.
  • 특정 조인 포인트에서 애스팩트에 의해 취해지는 조치이다.

 

Advice 순서

어드바이스는 기본적으로 순서를 보장하지 않는다.

순서를 지정하고 싶으면 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 애너테이션을 적용해야 한다.

  • 어드바이스 단위가 아니라 클래스 단위로 적용할 수 있다.
  • 하나의 애스펙트에 여러 어드바이스가 존재하면 순서를 보장 받을 수 없다.

애스펙트를 별도의 클래스로 분리해야 한다.

 

Advice 종류

Before

  • 조인 포인트 실행 이전에 실행한다.
  • 타겟 메서드가 실행되기 전에 처리해야할 필요가 있는 부가 기능을 호출 전에 공통 기능을 실행한다.
  • Before Advice룰 구현한 메서드는 일반적으로 리턴타입이 void이다.
  • 주의점으로 메서드에서 예외를 발생시킬 경우 대상 객체의 메서드가 호출되지 않게 된다는 점이 있다.
  • 작업 흐름을 변경할 수 없다.
  • 메서드 종료 시 자동으로 다음 타겟이 호출된다. (예외가 발생하면 다음 코드는 호출되지 않는다.)

 

After returning

  • 조인 포인트가 정상 완료 후 실행한다.
  • 메서드가 예외 없이 실행된 이후에 공통 기능을 실행한다.
  • 메서드 실행이 정상적으로 반환될 때 실행된다.
  • returning 속성에 사용된 이름은 어드바이스 메서드의 매개변수 이름과 일치해야 한다.
  • returning 절에 지정된 타입의 값을 반환하는 메서드만 대상을 실행한다.

 

After throwing

  • 메서드가 예외를 던지는 경우에 실행한다.
  • 메서드를 실행하는 도중 예외가 발생한 경우 공통 기능을 실행한다.

 

After (finally)

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

 

Around

  • 메서드 호출 전후에 수행하며 가장 강력한 어드바이스이다.
  • 메서드 실행 전 & 후, 예외 발생 시점에 공통 기능을 실행한다.
  • 어드바이스의 첫 번째 파라미터는 ProceedingJoinPoint를 사용해야 한다.
  • proceed()를 통해 대상을 실행한다.
  • proceed()를 여러번 실행할 수 있다.

 

@Around만 있어도 모든 기능 수행이 가능하다.

가장 강력한 어드바이스이며 대부분의 기능을 제공하지만 타겟 등 고려해야할 사항이 있을 때 정상적으로 작동이 되지 않는 경우가 있기도 하다.

  • @Before, @After와 같은 어드바이스는 기능은 적지만 원하는대로 작동되고 코드도 단순하다.
  • 각 애너테이션만 봐도 타겟 실행 전에 어떤 일을 하는지 명확하게 알 수 있다.
  • 좋은 설계는 @Around만 사용해서 모두 해결하는 것보다는 제약을 가지더라도 실수를 미연에 방지하는 것이다.
  • 제약을 두면 문제 자체가 발생하지 않게 하며, 역할이 명확해진다.

'코드스테이츠' 카테고리의 다른 글

코드스테이츠 40일차 / Section 2 회고  (2) 2022.06.22
코드스테이츠 39일차  (0) 2022.06.21
코드스테이츠 37일차  (0) 2022.06.17
코드스테이츠 36일차  (0) 2022.06.16
코드스테이츠 35일차  (0) 2022.06.15