ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AOP
    Back-end Developer/Server, Spring 2020. 6. 29. 19:39

    본 포스팅은 Spring docs 내용을 기준으로 정리된 글입니다.

    좀 더 자세한 내용은 해당 링크를 참고해 주세요.

     

    일반적으로 관점이라 하면, 사람의 관점은 서로 다르다. 어떻게 보느냐에 따라 다른 결과가 나타난다.

    뭐 이런 이야기를 많이 합니다.

    하지만 AOP에서 쓰이는 용어들은 직관적인 의미와는 약간 상이한 뜻을 가집니다.

    (물론 관점을 여러가지로 고려해본다는 의미와는 꽤나 상통합니다.)

    따라서, 용어에 대한 혼동을 가져올 수 있으니 주의하시기 바랍니다.

     

    AOP (Aspect Oriented Programming)

    관점 지향 프로그래밍이라고 불립니다.

    AOP는 프로그램 구조에 대한 견해를 조금 다른 방식으로 접근해 OOP를 보완합니다.

    OOP의 핵심 모듈화 단위는 class인데, AOP의 핵심 모듈화 단위는 aspect입니다.

    AOP 다수의 객체와 타입을 아우르는 관심사(concern)의 모듈화를 가능하게 합니다.

     

    concern이 뭐길래 모듈화를 필요로 할까요?

     

    객체지향 5 원칙 중 SRP(단일 책임 원칙)는 다들 들어보셨을 겁니다.

    책임이라 하면 일반적으로는 해당 핸들러에 맞는 비즈니스 로직과 같은 핵심적인 기능이 주된 책임이 될 것입니다.

    하지만, 실제 개발하는데 있어 이러한 기능 말고도 부수적인 것들이 들어가기 마련이죠.

    또한 부수적이라고 해서 필요없는 건 아닙니다.

    필요한 로직이지만 해당 핸들러(모듈) 등에서 주된 로직은 아닌 것들을 concern이라 생각하시면 우선은 이해가 되실듯 합니다.

     

    이러한 concern의 예시로는 로깅, 보안, 트랜잭션 등이 있습니다.

    부수적이나 오히려 어떤 모듈에선 꼭 필요한 기능들인데요. 이들은 다양한 모듈(전체 애플리케이션)에서 유사한 기능으로 사용되고 있을 가능성이 높죠.

    따라서 이들을 Cross Cutting Concern(횡단 관심사)이라 부르고 이들을 한데 모아 개발한다는 것이 AOP의 기본 개념입니다.

     

    Cross Cutting Concern에 대한 이해하기 좋은 그림들이 많아 이를 참고해 저도 예시를 하나 그려보았습니다.

    about cross cutting concern

    그림과 같이 다양한 모듈에서 비슷한 기능으로 걸려있는 모습입니다.

    이러한 관심사를 묶어 따로 모듈화 하고 필요시에 호출해주면 좀 더 유연한 코드를 작성할 수 있겠죠.

     

     

    어쨌든 중요한 기능을 하는 만큼

    AOP의 용어는 상당히 많은데, 이러한 용어(기능)들을 통해 AOP를 실현할 수 있습니다.

    의미를 제대로 알아야 기능 구현도 잘 할 수 있겠죠.

     

    Aspect (Advice + Point cut)

    concern을 모듈화 한 것으로, transaction management가 자바 엔터프라이즈 애플리케이션의 concern 중 가장 좋은 예시라 할 수 있습니다. Spring AOP에서 Aspect는 일반적인 클래스나, 이러한 클래스에 '@Aspect' annotation이 붙어있는 클래스를 사용하여 구현됩니다.

     

    Advice (해야할 작업)

    한 aspect의 특정 Join point에서 실행되는 동작을 의미합니다. Advice에는 'around', 'before', 'after 등이 있습니다. 스프링 등에 포함된 대부분의 AOP는 Advice를 인터셉터로 모델링하고, Joint point 주위에 일련의 인터셉터를 설정합니다.

    표현 설명
    @Before Target의 JoinPoint를 호출하기 전에 실행되는 코드.
    코드의 실행 자체에는 관여할 수 없다.
    @AfterReturning 모든 실행이 정상적으로 이루어진 후에 동작하는 코드.
    @AfterThrowing 예외가 발생한 뒤에 동작하는 코드.
    @After 정상적으로 실행되거나 예외가 발생했을 때 구분 없이 실행되는 코드.
    @Around 메소드의 실행 자체를 제어할 수 있는 가장 강력한 코드.
    직접 대상 메소드를 호출하고 결과나 예외를 처리할 수 있다.

     

    Join point (method/Advice 실행 지점)

    프로그램이 실행되는 동안 메소드의 실행이나 예외처리가 발생되는 지점을 의미합니다. 즉, Advice가 적용될 위치를 의미합니다. Spring AOP에서 Join point는 항상 메소드의 실행을 나타냅니다.

     

    Pointcut (적용할 위치, join point 선별)

    Join point로 매칭 될 곳을 지정합니다. Advice는 Pointcut expression과 연관되어 Pointcut을 통해 알맞는 Join point를 찾고 작동합니다. Pointcut expression에 의해 지정된 Join point의 컨셉은 AOP의 핵심이라 할 수 있습니다. Spring의 AspectJ 기본 언어는 Pointcut expression 입니다.

    표현 설명
    execution(@execution) 메소드 기준 Pointcut 설정
    within(@within) 특정한 타입(클래스) 기준 Pointcut 설정
    this 주어진 인터페이스를 구현한 객체 대상 Pointcut 설정
    args(@args) 특정한 파라미터를 가지는 대상 Pointcut 설정
    @annotation 특정한 어노테이션이 적용된 대상 Pointcut 설정

    즉, 'Join point 여러개를 선별해 묶어둔 것이 pointcut이다' 라고 이해하시면 됩니다.

     

    Target Object (적용이 되는 대상)

    하나 또는 그 이상의 Aspect에 의해 Advice가 적용되는 객체입니다. Adviced Object라고도 불립니다. Spring AOP가 runtime proxy를 통해 구현므로 해당 객체는 항상 프록시 객체입니다.

     

    AOP Proxy (Proxy 기반 AOP)

     Spring IoC 연동해 enterprise application에서 가장 흔히 사용하는 패턴의 문제 대한 해결책 제공합니다. JDK dynamic proxy와 CGlib proxy를 통해 AOP Proxy를 구현할 수 있습니다.

     

    Weaving (Object와 Aspect를 연결)

    Weaving은 다른 Application 타입이나 객체를 연결하여 Adviced(관점지향) 객체를 생성하는 것이 목적입니다. 종류에는 'compile time', 'load time', 'runtime'이 있으며 Spring 또는 순수 JAVA AOP는 runtime에 Weaving을 수행합니다.

     

     

     

    이러한 여러가지 기능들을 통해 동일한 concern들을 한 Aspect에 묶고 Aspect 내부에서 이 일들을 어디에 (join point을 기반으로 point cut 설정하고) 어떻게 적용(advice를 지정)할지 설정하여 관점지향 프로그래밍을 수행할 수 있습니다

    각 기능들이 서로 연관이 많기 때문에 도식화해서 보시면 조금 이해가 빠르지 않을까 싶습니다.

    추가적으로 내용에 포함된 용어들도 알아보겠습니다.

     

     

    Weaving

    횡단 관심사를 Method가 실행되는 조인포인트에 코드를 적용 시켜, 실제 메소드에 코드가 있는 것 처럼 실행 하는 행위

    즉, Advice로 모아둔 aspect들을 핵심 로직과 함께 동작시키는 것 (Target에 적용)

    -> 지정된 객체에 Aspect를 적용해 새로운 proxy 객체를 생성하는 과정

     

     

    weaving 종류

     

    compile-time

    로드타임런타임에성능적인부하가없음.그러나별도의 컴파일링이 필요.

     

    load-time

    class 로딩시 약간의 부하 존재. 로드타임 weaver(java agent)를 설정 필요.

    class 파일을 로딩하는 시점에 byte code로 변경하는 기법

     

    run-time

    런타임 적용, Spring AOP에서 사용됨

    최초의 bean을 만드는 데에 성능 부하가 약간 존재.

    Proxy를 생성하여 실제 타깃(Target) 오브젝트의 변형없이 위빙을 수행, 메소드 호출시 weaving 수행.

     

    Spring Proxy

    Spring AOP는 Proxy 기반 이며 또한 Runtime weaving(RTW)을 수행한다 말씀드렸는데요.

    RTW에서 사용되는 프록시 두가지에 대해 간략히 소개드립니다.

     

    JDK dynamic proxy

    proxy 자동 생성기로 dynamic proxy를 생성할 수 있습니다.

    Proxy Factory에 의해 런타임 시 동적으로 만들어지는 객체입니다. JDK dynamic proxy는 적어도 하나의 interface를 구현해야하는 경우 사용되며, Interface에 대한 명세를 기준으로 proxy를 생성합니다.

     

    CGLIB proxy (3rd party)

    타겟 객체가 interface를 구현하지 않는다면 CGLIB proxy를 사용할 수 있습니다.

    CGLIB은 타겟 객체를 상속받아 구현되며, interface를 따로 만들 필요는 없습니다.

    인터페이스에 정의되지않은 메소드를 필요로하거나, 프록시화 된 객체를 구체적인 타입으로 메소드에 넘겨줘야하는 경우 CGLIB의 사용을 강제할 수 있습니다.

     

     

    이렇게 AOP 내용을 정리할 수 있었습니다.

    AOP가 어떻게 적용되는지도 중요했지만, proxy의 비중이 상당히 높다는 것을 느낄 수 있었습니다.

     

     

    다음 포스팅에선 REST API나 MVC 패턴 관련한 이야기를 써볼까 합니다.

    잘못된 내용이나, 이해가 잘 안되는 부분은 댓글로 알려주시면 늦지않게 답변 드리겠습니다. 감사합니다.

    반응형

    'Back-end Developer > Server, Spring' 카테고리의 다른 글

    REST API (2)  (0) 2020.07.19
    REST API (1)  (0) 2020.07.17
    POJO  (0) 2020.06.28
    Proxy (bean scope)  (0) 2020.06.24
    Bean 그리고 scope  (0) 2020.06.23

    댓글

Designed by minchoba.