AOP 란? (AOP 의 실행과정)

반응형

 

AOP 가 등장한 배경

AOP 란 (Aspect-Oriented Programing) OOP 의 한계를 극복하기 위해 등장한 패러다임입니다. 

OOP는 대부분의 기능을 캡슐화 할 수 있지만, 중복되는 로직이나 횡단관심사의 경우에는 분리하기 어려운 경우가 많습니다. 

더보기

횡단관심사

횡단 관심사란 소프트웨어 개발에서 여러 계층이나 묘둘에 걸쳐 공통적으로 영향을 미치는 관심사입니다.
예로는 로깅, 트랜잭션 관리, 성능 모니터링이 있습니다. 

출처 : 미나미 블로그(https://minaminaworld.tistory.com/153)

 

이를 해결하기 위해 AOP 패러다임을 이용해 횡단 관심사를 분리해 OOP 의 장점을 살리고 중복되는 로직을 줄일 수 있게 된 것입니다. 

 

조금 더, 깊게 생각해보면 OOP 의 5대 원칙 중 하나인 SRP 를 위배 한다는 것을 알 수 있습니다. AOP 패러다임을 사용하지 않는다면 비즈니스 로직을 구현한 메서드에 공통 관심사가 뒤엉켜 하나의 책임이 아닌 다중 책임을 가지게 됩니다. 또한 AOP 를 통해 확장에는 열려있어야 하는 OCP 의 원칙도 지킬 수 있게 됩니다.



위에서 언급한 중복, 로직의 뒤엉킴 등의 문제를 해결, 횡단 관심사를 분리해 중앙화하고 재사용할 수 있도록 한 것이 관점의 개념입니다.  



결론적으로 AOP 는 횡단 관심사를 별도의 모듈로 분리하여 코드의 중복, 유지보수가 편리하게 만들어주는 프로그래밍의 패러다임이라고 할 수 있습니다. 

 


“큰 힘에는 큰 책임이 따른다!”라는 말처럼, 애스펙트는 강력한 도구이므로 신중하게 사용하지 않으면 원하는 목적과는 정반대로 유지 관리하기 어려운 앱이 될 수 있다. (피터 파커)

 

 

관점이라는 도구는 강력한 도구이기 때문에 신중하게 사용해야 합니다.  

 

AOP 실행 과정 

위에서 우리는 AOP 의 등장 배경에 대해 함께 생각해보는 시간을 가졌습니다. 그렇다면 AOP 는 어떻게 사용, 실행 되는지 알아보는 시간을 가지면 좋겠습니다.

AOP의 실행과정을 이해하기 위해서는 몇가지의 개념이 필요합니다. 개념에 대해서는 간단하게 언급하고 궁금하다면 더 찾아보는 것을 추천드립니다. 

더보기
  • 프록시

프록시란 객체와 객체 간의 연결을 직접연결이 아닌 프록시라는 대리자를 통해 간접적으로 연결하는 것을 말합니다. 
이 과정에서 추가적인 로직이나 필요작업을 추가해줄 수 있습니다. 

  • 팩토리 패턴 

팩토리 패턴이란 객체 생성을 담당하는 공장을 만들어 필요 시 객체를 생성하는 역할을 분리 하는 것입니다. 
이렇게 될 경우 클래스에 직접적인 객체 생성을 하지 않고 참조를 통해 객체를 얻어올 수 있습니다. 유지보수와 객체 생성의 로직을 캡슐화 할 수 있는 장점이 생깁니다. 

  • AOP 의 핵심 용어들 

Aspect : 횡단관심사를 분리해 모듈화 한 것 

JoinPoint : 프로그램 실행 중 횡단 관심사를 적용할 수 있는 지점 

PointCut : JoinPoint 를 필터링 할 수 있는 규칙 

Advice : JoinPoint 에서 실행되는 실제 동작

Target : AOP 가 적용되는 객체 

 

접은 글의 개념을 어느 정도 숙지한 상태에서 AOP 의 실행과정을 살펴보도록 하겠습니다. 

 

  1. 개발자의 AOP 설정 (@Aspect , XML, Java Config)

  2. 스프링 컨테이너 초기화 (BeanPostProcessor 등록 (AnnotationAwareAspectJAutoProxyCreator 나 AutoProxyCreator 중 하나가 등록 됨.))

  3. 컨테이너가 모든 빈을 생성하고 초기화 합니다. 등록 된 AutoProxyCreator 가 빈 생성 과정에서 AOP 적용 대상을 식별합니다(@Aspect , PointCut 매칭 클래스)

  4. 프록시( JDK 동적 프록시(인터페이스가 있는 경우 사용) , CGLIB 프록시(클래스 기반 프록시 생성) )를 생성합니다(빈 후처리기의 개념이 필요 함). 프록시 객체 내부에 AdvisedSupport 객체가 생성되며, 다음정보를 가집니다. Target 객체, Advisor 목록(Advice, PointCut), 프록시 설정 정보

  5. 빈 팩토리는 원본 빈 대신 생성된 프록시 객체를 컨테이너에 등록하게 됩니다.

  6. 클라이언트가 빈의 메서드를 호출

  7. 프록시가 호출을 가로채고 Advisor 를 확인  Advice 실행 후 Target 객체의 메서드를 호출

  8. 결과 반환 하거나 추가 처리를 수행 

 

예시 코드 

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
}



@Service
public class MyService {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

// Main Application
MyService service = context.getBean(MyService.class);
service.doSomething();

PointCut에 해당되는 MyService 를 AOP 대상으로 식별하고, 프록시 객체를 생성합니다. 클라이언트가 doSomething() 메서드를 호출했을 때,  프록시 객체가 호출 되고 log 를 찍고 service 의 메서드가 실행되는 것을 알 수 있습니다. 




   

스프링 공식문서 내용 정리

Spring AOP 는 순수 자바로 구현되었기 때문에 특별한 컴파일 과정이 필요하지 않습니다. 

 

궁극적인 목표는 가장 완벽한 AOP 구현을 제공하는 것이 아니고 AOP 구현과 Spring IoC 간의 긴밀한 통합을 제공해 엔터프라이즈 애플리케이션의 일반적인 문제를 해결하는 데 도움이 되는 것입니다. 

 

AspectJ Support 는 어노테이션이 있는 일반 Java 클래스로 관점을 선언하는 스타일입니다. 



Declaring Advice 를 통해 메서드의 실행 시점을 지정해 사용이 가능합니다. 



 

TMI

위빙(weaving) 이란? 

DI를 사용하든 컨텍스트에서 빈을 얻을 때는 언제나 빈 대신 프록시 객체를 받게 된다. 이렇게 래핑 하는 것을 위빙이라고 한다. 



오늘은 AOP 에 대해 알아보았습니다. 아직은 부족함이 많지만 끊임없이 성장해보도록 하겠습니다. 감사합니다.