ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 맨날 까먹는 AOP 정리
    Java/Spring 2019. 7. 20. 01:57
    반응형

    AOPAspect-Oriented Programming 의 약자입니다. AOP 로 로직상에서 문제를 해결하고자 하는 핵심 기능과 공통 기능을 분리하는 프로그래밍 방법입니다.

    AOP 의 주요 키워드

    Target

    공통 기능을 부여할 대상입니다. 즉, 핵심 기능을 담당하는 비즈니스 로직이고, 어떤 관심사들과도 관계를 맺지 않습니다.

     

    Aspect

    여러 핵심 기능에 적용될 관심사 모듈입니다. Aspect 에는 구체적인 기능을 구현한 Advice 와 Advice 가 어디에서 적용될지를 결정하는 PointCut 을 포함하고 있습니다.

     

    Advice

    Advice 는 공통 기능을 담은 구현체입니다. Advice 는 Aspect 가 무엇을 언제 적용할 지를 정의합니다.

     

    PointCut

    PointCut 은 공통 기능이 적용될 대상을 결정합니다.

     

    JoinPoint

    Advice 가 적용될 지점을 의미합니다. Spring 에서는 메서드만이 JoinPoint 로 제공하고 있습니다.

     

    Proxy

    Target 을 랩핑하여 Target 의 요청을 대신 받아주는 오브젝트입니다.

     

    Weaving

    지정된 객채에 Aspect 를 적용해서 새로운 프록시 객체를 생성하여 적용하는 것을 말합니다. 즉, 공통 코드를 핵심 로직 코드에 삽입하는 과정입니다.

    Advice 정리

    @Before

    Advice 의 Target 메서드가 호출되기 전에 실행되는 Advice 입니다.

     

    @After

    Advice 의 Target 메서드가 호출된 후에 그 결과에 상관없이(성공 or 실패) 실행되는 Advice 입니다.

     

    @AfterReturning

    Target 메서드가 정상적으로 실행된 후에 실행되는 Advice 입니다.

     

    @AfterThrowingAdvice

    Target 메서드가 수행도중 예외가 발생했을 때 예외를 던지게 되면 실행되는 Advice 입니다.

     

    @Around

    Advice 가 Target 메서드를 감싸서 Target 메서드 호출 전과 후에 실행되는 Advice 입니다. @Around 는 ProceedingJoinPoint 의 proceed() 를 수행하는데, proceed() 의 리턴 값이 sub 메서드의 리턴 값이다. 즉, @Advice 내부에서 결과값을 제어할 수 있다.


    PointCut 표현식

    포인트 컷에는 아래와 같은 명시자를 이용할 수 있습니다.

    • execution : Advice 를 적용할 메서드를 명시할 때 사용합니다.
    • within : 특정 타입에 속하는 메서드를 JoinPoint 로 설정되도록 명시할 때 사용합니다.
    • bean : 스프링 버전 2.5 버전부터 지원하기 시작했으며, 스프링 빈을 이용하여 JoinPoint 를 설정합니다.

    execution 명시자

    execution([수식어] 리턴 타입 [클래스 이름].이름(파라미터))

    • 수식어 : public, private 등 수식어를 명시합니다. (생략가능)
    • 리턴 타입 : 리턴 타입을 명시합니다.
    • 클래스 이름 및 이름 : 클래스 이름과 메서드 이름을 명시합니다. (클래스 이름은 풀 패키지 명으로 명시해야합니다. 클래스 이름은 생략할 수도 있습니다.)
    • 파라미터 : 메서드의 파라미터를 명시합니다.
    • " * " : 모든 값을 표현합니다.
    • " .. " : 0개 이상을 의미합니다.

    ex)

    execution(public Integer com.edu.aop..(*))

    • com.edu.aop 패키지에 속해있고, 파라미터가 1개인 모든 메서드

    execution(* com.edu...get(..))

    • com.edu 패키지 및 하위 패키지에 속해있고, 이름이 get 으로 시작하는 파라미터가 0개 이상인 모든 메서드

    execution(* com.edu.aop..Service.(..))

    • com.edu.aop 패키지 및 하위 패키지에 속해있고, 이름이 Service 로 끝나는 클래스의 파라미터가 0개 이상인 모든 메서드

    execution(* com.edu.aop.BoardService.*(..))

    • com.edu.aop.BoardService 클래스에 속한 파라미터가 0개 이상인 모든 메서드

    execution(* some(, *))

    • 메서드 이름이 some 으로 시작하고 파라미터가 2개인 모든 메서드

    within 명시자

    ex)

    within(com.edu.aop.SomeService)

    • com.edu.aop.SomeService 클래스의 모든 메서드

    within(com.edu.aop.*)

    • com.edu.aop 패키지의 모든 메서드

    within(com.edu.aop..*)

    • com.edu.aop 패키지 및 하위 패키지의 모든 메서드

    bean 명시자

    ex)

    bean(someBean)

    • 이름이 someBean인 빈의 모든 메서드

    bean(somm*)

    • 빈의 이름이 some 으로 시작하는 빈의 모든 메서드

    아래의 @PointCut 애너테이션을 이용하여 JoinPoint 를 지정할 수 있다.

    @Component
    @Aspect
    public class SampleAspect {
    
        @Pointcut("@annotation(com.edu.aop.Sample)")
        private void pointcut() { }
    
        @AfterReturning(pointcut = "pointcut()", returning = "returnValue")
        public Object afterReturning(JoinPoint joinPoint, Object returnValue) {
                    //TODO : Something logic...
            return returnValue;
        }
    }

     모든 어드바이스는 org.aspectj.lang.JoinPoint 타입의 파라미터를 어드바이스의 첫 파라미터로 선언할 수 있다. Around advice 는 JoinPoint 의 하위 클래스인 ProceedingJoinPoint 타입의 파라미터를 필수적으로 첫 파라미터로 선언해야 한다.

     JoinPoint 인터페이스는 getArgs() (메서드 argument를 반환한다.), getSignature() (advice되는 메서드의 시그니처를 반환한다.), toString() (advice 되는 메서드의 유용한 설명을 출력한다.) 같은 다수의 유용한 메서드를 제공한다.


    유용한 자료

    [Spring 레퍼런스] 8장 스프링의 관점 지향 프로그래밍 #2 :: Outsider's Dev Story

    반응형

    'Java > Spring' 카테고리의 다른 글

    [Spring Security] CORS 에 대하여  (0) 2019.11.11
    Spring Security 정리  (1) 2019.10.05
    [Spring] @Transactional 속성 정리  (0) 2019.09.06
    JWT 에 대한 간단 정리  (0) 2019.08.04
    Spring AOP PointCut 표현식 정리  (0) 2019.07.21

    댓글

Designed by Tistory.