ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] AOP 사용하기
    Software Development/Java 2020. 12. 20. 20:16

    스프링 프레임워크를 이야기할 때 빠지지 않고 등장하는 단어 중 하나가 AOP입니다. AOP는 IoC 그리고 DI와 함께 스프링 프레임워크에서 중요한 내용입니다. AOP는 Aspect Oriented Programming의 약자로 관점지향 프로그래밍이라고 합니다.

     

    AOP란?

    스프링의 여러 가지 장점 및 특징을 이야기할 때 빠지지 않고 등장하는 것이 바로 AOP입니다. AOP를 OOP를 대체하는 개념으로 오해하기도 합니다. AOP는 OOP를 더욱 OOP답게 사용하도록 도와 주는 개념으로 AOP를 이해하기 위해서는 우선 OOP의 이해가 필요합니다. 따라서 OOP에 대해서 먼저 이야기 하겠습니다.

     

    객체지향이란 관심사가 같은 기능과 데이터를 모아서 재사용이 가능한 객체로 캡슐화하는 것을 의미합니다. 객체지향 개념을 잘 모르는 사람도 자바를 이용해 애플리케이션을 개발하면서 수많은 클래스를 생성하게 됩니다. 또한 이미 만들어져 있는 클래스를 사용하고 또 새로운 클래스를 직접 만들어서 사용합니다. 이미 만들어진 클래스를 사용하고 또 새로운 클래스를 직접 만들어서 사용하기도 하는데 이러한 클래스들은 프로젝트 내의 여러 곳에서 반본적으로 재사용되면서 생산성이 높아집니다.

     

    애플리케이션을 개발하다 보면 객체의 핵심코드 외에도 여러가지 기능이 들어갑니다. 메서드 호출 전후의 로그, 데이터 검증 및 확힌 로그, 예외처리 등 핵심 기능과 관계는 없지만 그렇다고 없어서도 안 되는 코드들이 삽입되면서 객체의 모듈화가 어려워지곤 합니다. 반복적인 코드를 삽입하지 않기 위해 만든 클래스도, 그 클래스를 반복적으로 사용하면서 코드의 재사용성이 떨어지고 생산성이 낮아지는 문제가 생깁니다.

     

    AOP는 애플리케이션 전반에서 사용되는 기능을 여러 코드에 쉽게 적용할 수 있도록 도와줍니다. 로그, 권한 체크, 인증, 예외처리 등은 애플리케이션의 대부분에 적용되어야 하는 기능입니다. 기존 프로그래밍에서는 공통적으로 사용하는 기능을 하나의 클래스로 만들어 놓더라도 해당 기능이 필요한 모든 부분에서 클래스를 생성하고 필요한 메서드를 호출해야만 했습니다. 어떠한 공통 기능을 사용해야 할 부분이 백 군데라고 하면, 백 군데의 코드에 직접 공통 기능을 추가해야 했습니다.

     

    기능에 공통적으로 들어가야 하는 기능이 있습니다. 권한 체크, 로그, 트랜잭션 등입니다. 계정이나 게시판, 계좌이체와 같은 기능을 개발하면서 직접 공통 기능을 넣어줘야 합니다.

     

    AOP는 이러한 문제를 관점이라는 개념을 통해서 해결하는 방법입니다. 계정, 게시판, 계좌이체라는 핵심 기느으이 관점에서는 권한, 로깅, 트랜잭션 등의 부가 기능 사이에 공통점이 없습니다. 이걸 바라보는 시점을 바꿔서 부가 기능의 관점에서 이해합니다. 부가 기능이 적용될 기점, 즉 핵심 로직의 시작이나 종료 시점에 그곳에서 필요한 부가 기능이 적용되기만 하면 됩니다.

     

    OOP를 더욱 OOP적으로 만들어주는 AOP

    AOP는 결국 공통된 기능을 재사용하는 것입니다. 물론 OOP도 공통된 기능을 하나의 객체로 만들고 이를 다른 객체에서 호출하는 식으로 구현됩니다.  하지만 공통 기능을 구현하기 위해 다시 다른 객체의 기능이 필요하다거나, 객체에서 다른 객체를 계속 호출해야 하는 등 객체 간 종속성이 강한 경우가 있습니다. 그러면 모듈화를 깔끔하게 하기 어렵습니다.

     

    AOP는 다른 객체의 호출과 상관없이 각강의 기능에만 집중해서 모듈로 만들 수 있습니다. 

     

    AOP의 주요 개념

    어드바이스

    어드바이스는 관점의 구현체로 조인포인트에 삽입되어 동작하는 것을 의미합니다. 스프링에서 어드바이스는 동작하는 시점에 따라 다섯 종류로 구분됩니다.

     

    종류 어노테이션 설명
    Before Advice @Before 대상 메서드가 실행되기 전에 적용할 어드바이스를 정의
    After returning Advice @AfterReturning 대상 메서드가 성공적으로 실행되고 결괏값을 반환한 후 적용할 어드바이스를 정의
    After throwing Advice @AfterThrowing 대상 메서드에서 예외가 발생했을 때 적용할 어드바이스를 정의 try/catch 문의 catch와 비슷한 역할
    After Advice @After 대상 메서드의 정상적인 수행 여부와 상관없이 무조건 실행되는 어드바이스를 정의. 즉 예외가 발생하더라도 실행된다. finally와 유사
    @Around Advice @Around 대상 메서드의 호출 전후, 예외 발생 등 모든 시점에 적용할 수 있는 어드바이스를 정의. 가장 범용적인 어드바이스

     

    포인트컷

    어드바이스를 적용할 조인포인트를 선별하는 과정이나 그 기능을 정의한 모듈을 의미합니다. 정규표현식이나 AspectJ의 문법을 이용해서 어떤 조인포인트를 사용할 것인지 결정합니다. 포인트것을 표현할 수 있는 명시자에는 여러 종류가 있지만 일반적으로 가장 많이 사용하는 명시자는 execution입니다.

     

    - execution

    가장 대표적이고 강력한 지시자로 접근 제어자, 리턴 타입, 타입 패턴, 메서드, 파라미터 타입, 예외 타입 등을 조합해 가장 정교한 포인트컷을 만들 수 있습니다.

     

    execution을 이용해서 포인트컷 표현식을 설정할 때 사용하는 표현이 있습니다. *는 모든 값이라는 의미를 표현합니다. 예를 들어 메서드 이름을 select*로 표현하면 select로 시작하는 모든 메서드가 선택됩니다. ..은 0개 이상이라는 의미를 표현합니다. 0개 이상은 파라미터, 메서드, 패키지 등 모든 것을 의미합니다. 패키지 구조를 표현하면 하위의 모든 패키지를 의미하고 파라미터를 표현할 때에는 파라미터 개수와 관계없이 모든 파라미터를 의미합니다. 

    execution(void get*(..)) - 리턴 타입이 void이고 메서드 이름이 get으로 시작하며, 파라미터가 0개 이상인 모든 메서드가 호출될 때

    execution(* service.Impl*()) - service 패키지 밑에 파라미터가 없는 모든 메서드가 호출될 때

    execution(* service.Impl*(..)) - service 패키지 밑에 파라미터가 0개 이상인 모든 메서드가 호출될 때

    execution(* service..get*(*)) - service 패키지 모든 하위 패키지에 있는 select로 시작하고 파라미터가 한개인 모든 메서드가 호출될 때

    execution(* service..get*(*, *)) - service 패키지 모든 하위 패키지에 있는 select로 시작하고 파라미터가 두개인 모든 메서드가 호출될 때

     

    execution 포인트컷 표현식은 AOP의 핵심입니다. 꼭 이해해야 합니다. 

     

    -within

    특정 타입에 속하는 메서드를 포인트컷으로 설정합니다. 

    within(service.Impl) - service 패키지 밑에 있는 Impl 클래스의 메서드가 호출될 때

    within(service.*Impl) - service 패키지 밑에 있는 Impl 이라는 이름으로 끝나는 메서드가 호출될 때

     

     

    - bean

    스프링의 빈 이름의 패턴으로 포인트컷을 설정합니다.

    bean(Impl) - Impl라는 이름을 가진 빈의 메서드가 호출될 때

    'Software Development > Java' 카테고리의 다른 글

    [Spring] JPA  (0) 2021.01.01
    [Spring] RESTful 이해하기  (0) 2020.12.26
    [Spring] 인터셉터 사용하기  (0) 2020.12.20
    [Spring] Logback 알아보기  (0) 2020.12.19
    [Spring] 스프링 프레임워크 이해하기  (0) 2020.12.15

    댓글

Designed by Tistory.