OOP에 대한 개념밖에 알지 못했었지만 스프링은 AOP. 관점 지향 프로그래밍 개념을 사용합니다.

 

AOP란, 같은 일을 하는 것들을 모든 객체에 적용 시키는 것을 의미합니다.

 

예를들어 트랜잭션 관리가 있다고 했을 때, 배달 주문을 하든, 포장 주문을 하든, 전화 주문을 하든 모든 주문들은 주문이 생성될 때 데이터베이스에 주문 정보를 저장하고, 결제가 성공하면 커밋(Commit)을 수행하고, 결제가 실패하면 롤백(Rollback)을 수행할 것입니다.

 

각각의 주문들에 이것들을 넣어주기보단 트랜잭션 관리 aspect(관점)를 각각의 pointcut(해당 시점,지점)에 advice(실행)하는 것이 AOP입니다.

 

트랜잭션 관리 뿐 아니라, 보안작업, 로깅작업, 캐싱작업 등 같은 작업이 여러곳에 쓰일 때 그 작업을 하나의 관점으로 보고 (Cross Cutting 공통 관심사항) 처리해주는 것이 바로 AOP입니다.

 

같은 작업이라면 상속을 통해서도 처리해 줄 수 있지 않을까? 하는 생각이 들었지만,

 

상속은 객체의 계층구조를 만드는데, 특정 작업을 한다고 해서 그것을 상속시키는건 OOP적이지 않은 발상인 것 같습니다.

 

interface를 만든다 하더라도 결국 구현체에서 계속 overriding을 해주어야 하는데 이것도 여간 귀찮은 작업이 아니죠.

 

AOP는 동일한 기능을 하는 작업들을 하나의 관점으로 보고 모듈화 시켜 다양한 객체에 적용시키는 것이라고 이해하면 되겠습니다.

 

OOP를 보완해주는 느낌이네요.

 

AOP와 OOP의 차이점은 다음과 같습니다:

  1. 초점:
    • OOP: 객체지향 프로그래밍에서는 프로그램을 객체들의 상호작용으로 모델링하고, 객체의 상태와 동작에 중점을 둡니다.
    • AOP: 관심사 분리를 통해 프로그램의 공통된 관심사를 분리하여 모듈화하고, 핵심 비즈니스 로직과 분리된 관심사를 적용하는 데 중점을 둡니다.
  2. 목적:
    • OOP: 코드의 재사용성, 유지보수성, 확장성 등을 개선하며, 객체들 간의 상호작용을 중심으로 프로그램을 구조화합니다.
    • AOP: 프로그램의 횡단 관심사(로그 기록, 보안, 트랜잭션 관리 등)를 분리하여 모듈화하고, 이를 여러 모듈에 적용함으로써 코드 중복을 줄이고 가독성을 향상시킵니다.
  3. 적용 방식:
    • OOP: 상속, 다형성, 캡슐화 등의 개념을 사용하여 클래스와 객체의 구조를 설계하고 구현합니다.
    • AOP: 어드바이스, 애스펙트, 포인트컷 등의 개념을 사용하여 핵심 비즈니스 로직에 영향을 주지 않고 공통된 관심사를 모듈화합니다.

그렇다면 이 AOP는 어떻게 작성할 수 있을까요?

 

Proxy를 이용해서 쉽게 구현할 수가 있습니다.

 

Proxy가 뭔지 잘 이해가 가지 않는다면 파이썬의 Decorator를 생각하면 됩니다.

 

wrapper 함수를 만들고  wrapper함수는 특정 함수를 인자로 받습니다.

 

wrapper함수에서 인자로 받은 함수를 실행을 시켜주는데 그 전 후에 특정 행동을 추가해 줄 수가 있죠.

 

그렇다면 그 wrapper 함수가 특정 작업을 하는 기능이고 그것이 여러곳에 쓰인다면?

 

그것이 바로 Aspect가 되겠죠!!

 

그럼 한번 만들어보도록 하겠습니다.

 

이제 인사를 할 때, person의 greet 메서드를 실행 시키기 전과 후에 추가 동작을 해주는 PersonProxy를 만들겁니다.

 

package com.duljji;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PersonProxy {

	@Autowired
	public Person person;
	
	public void greet() {
		
		//인사하기 전에 하는 행동
		System.out.println("사람 발견!!");
		//인사
		person.greet();
		
		//인사한 후에 하는 행동
		System.out.println("안부 묻기");
	}
}

person 객체의 의존성을 주입하고 똑같이 greet 메소드를 만듭니다.

 

하지만 이 greet메소드는 person.greet을 실행시키기 이전과 이후에 추가 동작을 수행합니다.

 

이렇게 Proxy 패턴을 사용하면 해당 메서드를 구현하기 이전과 이후에 추가적인 행동들을 구현해 줄 수가 있습니다.

 

그럼 저 이전의 위치에 관점들을 실행하는 advice들을 넣어주면 되겠군요!!

 

아!! 그럼 스플이 컨테이너의 AOP는 해당 메서드를 이런식으로 실행을 시켜서, 실행 전후에 동작을 추가해줄 수 있구나! 라고 이해하면 되겠습니다. 

 

이제 스프링 컨테이너에게 AOP를 시켜보도록 하겠습니다.

+ Recent posts