실제 사물을 프로그래밍으로 옮겨와 모델링하는 것
사물 (Object) = 속성 (Variable) + 행위 (Method)
<OOP의 핵심>은 공통된 목적을 띈 데이터와 동작을 묶어 하나의 객체로 정의하는 것
기능을 재사용할 수 있는 것이 큰 장점
관심사 분리 (Separation of Concerns, SoC)의 디자인 원칙을 준수해야함
OOP 모듈화의 핵심 단위 ➜ 클래스
비즈니스 클래스에 횡단 관심사와 핵심 관심사가 공존하게 되는데,
이 때 메소드 복잡도가 증가하여 비즈니스 코드 파악이 어렵고,
부가 기능의 불특정 다수 메소드가 반복적으로 구현되어 횡단 관심사의 모듈화가 어려움
👉 OOP의 관심사 분리에 대한 한계를 해결하고자 AOP 등장 ⭐
✔️ 핵심 관심사 ( Core Concerns )
- 핵심 기능
- 객체가 제공하는 고유의 기능
⠀
Ex. 결제 기능, 알림 기능 등
✔️ 횡단 관심사 ( Cross-cutting Concerns )
- 핵심 기능을 보조하기 위해 여러 클래스에 걸쳐 공통으로 사용되는 부가 기능
➜ 중복 코드 생김 ( AOP 방식으로 해결 )- 핵심 기능과 함께 사용 ( 단독 X )
⠀
Ex. 로깅, 보안, 트랜잭션, 로그 추적 로직 등
✔️ SoC ( Separation of Concerns )
- 컴퓨터 프로그램을 구별된 부분으로 분리시키는 디자인 원칙
- 하나의 모듈에서 여러가지의 관심사를 가지고 처리하면 복잡성이 높으니,
관심사를 여러개로 분리하여 하나의 관심사는 하나의 기능을 가지도록 구성하는 것
✔️ 모듈 ( Module )
➜ 특정 기능별로 나누어지는 프로그램 덩어리
📌 객체 지향 프로그래밍 (OOP) 관련 포스팅
기존과 다른 프로그램 구조 사고 방식을 제공함으로써
객체 지향 프로그래밍(OOP)의 부족한 부분을 보완
관심사(기능)의 분리와 핵심 관심사에서 횡단 관심사를 분리하여
분리한 부가 기능을 Aspect라는 모듈 형태로 만들어 설계/개발 하는 방법
➜ 객체 지향적 가치를 높일 수 있게 함
여러 유형과 객체 간에 발생하는 문제의 모듈화를 가능하게 함
AOP의 모듈화의 핵심 단위 ➜ 관점 (Aspect) (기능)
( OOP의 모듈화의 핵심 단위 ➜ 클래스 (class) )
👉 위 사진을 보면,
각 핵심 관심사(핵심 기능)에 공통적으로 들어가는 기능인 횡단 관심사(부가 기능)을 분리하여 공통적으로 넣어주고 있음 !
💡 Spring DI 가 의존성(new) 에 대한 주입이라면
Spring AOP 는 로직(code) 주입이라고 볼 수 있음 !!
✔️ Aspect
- 여러 객체에 공통으로 적용되는 기능 ( 횡단 관심사 )
- Aspect = 어드바이스(Advice) + 포인트컷(PointCut)
( 부가 기능을 정의한 코드인 어드바이스(Advice)와
어드바이스를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합친 개념 )
📌 AOP 관련 용어는 아래 포스팅을 참고해주세요.
1. Spring은 프록시 기반 AOP를 지원
Spring은 핵심 기능(Target) 객체에 대한 프록시를 만들어 제공
핵심 기능(Target)을 감싸는 프록시(Proxy)는 런타임 시에 생성됨
✔ 프록시 ( Proxy )
➜ 어드바이스(Advice)를 타겟(Target) 객체에 적용하면서 생성되는 객체
( 부가기능을 핵심기능에 적용하면서 생성되는 객체 )
2. 프록시(Proxy)가 호출을 가로챔(Intercept)
Ex.
- 전처리 어드바이스(
@Before
)의 경우,
프록시는 타겟 객체에 대한 호출을 가로챈 다음 어드바이스의 부가 기능 로직을 수행하고 난 후에 타겟의 핵심기능 로직을 호출
⠀⠀- 후처리 어드바이스(
@After
)의 경우,
타겟의 핵심 기능 로직 메서드를 호출한 후에 부가 기능(어드바이스)을 수행
3. Spring AOP는 메서드 조인 포인트만 지원
Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인 포인트만 지원
핵심 기능(Target)의 메서드가 호출되는 런타임 시점에만 부가기능(Advice)을 적용할 수 있다.
반면에 AspectJ 같은 고급 AOP 프레임워크를 사용하면 다양한 작업에 부가 기능 적용 가능
Ex. 객체의 생성, 필드값의 조회/조작, static 메서드 호출 및 초기화 등에 적용 가능
AOP 기능 구현을 위해 만든 프록시 객체
Ex. 같은 인터페이스를 구현하고 있는 실제 요청 처리 객체와 프록시 객체를 만들고, 프록시 객체가 대신하여 실제 요청 처리를 가짐
스프링에서 생성하는 AOP 프록시는 JDK 동적 프록시
or CGLIB 프록시
임
✔️ 프록시 (Proxy)
- '대리' 라는 의미
- 다른 무언가와 이어지는 인터페이스 역할을 하는 클래스
- 타겟을 감싸서 요청을 대신 받아주는 랩핑 클래스
( Spring에서는 Proxy를 이용해 OOP의 5대 원칙 중 하나인 OCP 적용 )- 프록시 객체 = 핵심 기능 외의 공통 기능(부가 기능)을 담은 객체
( 어드바이스를 타겟 객체에 적용하면서 생성되는 객체 )
➜ 원래 객체를 감싸서 client의 요청을 대신 처리함
Spring AOP는 Proxy의 메커니즘을 기반으로 AOP Proxy를 제공하고 있음 !
위 그림처럼 Spring AOP는 사용자의 특정 호출 시점에 IoC 컨테이너에 의해 AOP를 할 수 있는 Proxy Bean을 생성해줌
동적으로 생성된 Proxy Bean은 핵심 기능(Target)의 메소드가 호출되는 시점에,
부가 기능(Aspect)을 추가할 메소드를 자체적으로 판단하고 가로채어 주입함
➜ 호출 시점에 동적으로 위빙을 하는 런타임 위빙(Runtime Weaving) 방식을 기반으로 함
Spring에선 런타임 위빙을 할 수 있도록 상황에 따라 JDK Dynamic Proxy 방식와 CGLIB 방식을 통해 Proxy Bean을 생성을 해줌
Spring은 AOP Proxy를 생성하는 과정에서 자체 검증 로직을 통해 타깃의 인터페이스 유무를 판단함
이 때 인터페이스의 유무에 따라,
핵심 기능(Target)이 하나 이상의 인터페이스를 구현하고 있는 클래스라면 ➜ JDK Dynamic Proxy 방식으로,
( But, 기본적으로 Spring은 인터페이스를 구현하는 것을 추천 )
인터페이스를 구현하지 않은 클래스라면 ➜ CGLIB의 방식으로 AOP 프록시를 생성
[참고] https://gmoon92.github.io/spring/aop/2019/04/20/jdk-dynamic-proxy-and-cglib.html
1. XML 기반의 POJO 클래스를 이용한 AOP 구현
부가기능을 제공하는 Advice 클래스를 작성
XML 설정 파일에 <aop:config>를 이용해서 Aspect를 설정
( ➜ 어드바이스와 포인트컷을 설정 )
2. @Aspect
애너테이션을 이용한 AOP 구현
@Aspect
애너테이션을 이용하여 부가기능을 제공하는 Aspect 클래스를 작성
( 이 때, Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함 )
XML 설정 파일에 <aop:aspectj-autoproxy />를 설정
✔️ POJO (Plain Old Java Object)
➜ Java로 생성하는 순수한 객체
✔️ POJO 프로그래밍
➜ POJO를 이용해서 프로그래밍 코드를 작성하는 것
⠀
But, 단순히 순수 자바 객체만을 사용한다는 말이 아니라,
⭐ (1) 객체지향의 원리에 충실하며 / (2) 다른 환경과 기술에 종속되지 않고 / (3) 다른 기술과 규약에 얽매이지 않은 객체를 사용하여 코드를 작성한다는 말
⠀
Spring Framework 사용 전에는 원하는 특정 기술이 있다면 그것을 직접적으로 사용하는 객체를 만들어 사용했었는데,
프로젝트가 커지면서 유지/보수/확장이 어려워지고 Java 언어는 사용하지만 객체지향 설계의 본질을 잃어버리는 문제점이 생김
👉 POJO 개념 등장
📌 POJO ( Plain Old Java Object ) 관련 포스팅
OOP의 단점을 보완하여 더 객체지향적이고,
반복적인 작업(부가 기능)을 통일해 한번에 하여 효율성을 높이기 위해
관점 지향 프로그래밍 즉, AOP (Aspect Oriented Programming) 기법을 사용한다.
이 AOP는 프로젝트 내의 여러 객체에 공통으로 적용되는 Aspect(부가 기능+넣을 위치)들만 기능별로 따로 묶어, 프록시 객체를 만들어서 한번에 처리하는 기법이다.
이 때, 따로 묶은 Advice들은 그 기능을 어디에(어느 핵심 기능(Target)에) 적용할 지 써줘야하는데
이는 포인트컷(Pointcut)을 활용하여 부가 기능(Advice)을 어느 위치에 넣을 건지 정해줄 수 있고,
어드바이스(Advice)를 활용하여 어느 시점에 넣을 건지 정해줄 수 있다.
여기서, AOP가 적용될 수 있는 모든 지점을 조인포인트(JoinPoint)라고 하고,
그 조인포인트들 중 구체적으로 여기 하겠다! 이게 포인트컷(Pointcut)이다.
즉, 포인트컷을 활용할 수 있는 모든 지점을 조인포인트라고 할 수 있다.
[참고] https://pangtrue.tistory.com/m/80
📌 다음 포스팅은 Spring AOP 용어 정리에 대한 내용입니다.
⠀
👉 Spring AOP(Aspect Oriented Programming) 용어 정리 !