상세 컨텐츠

본문 제목

Spring AOP (Proxy) - Logging 적용

Spring/개념

by Chan.94 2021. 10. 8. 20:40

본문

반응형

AOP란

AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다.
관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화 하겠다는 것이다.
소스 코드상에서 다른 부분에 계속 반복해서 쓰는 코드들을 발견할 수 있는 데 이것을 흩어진 관심사 (Crosscutting Concerns)라 부른다. 

동작시점 설명
Before 메소드 실행 전에 동작
After 메소드 실행 후에 동작
After-returning 메소드가 정삭적으로 실행된 후에 동작
After-throwing 예외가 발생한 후에 동작
Around 메소드 호출 이전, 이후, 예외발생 등 모든 시점에서 동작

AOP 용어

  • Aspect
    애플리케이션의 관심사를 모듈화한 것으로 주로 부가적인 기능(로깅, 보안, 트랜잭션 관리 등)이 Aspect로 구현
  • Join Point
    Aspect가 적용될 수 있는 시점
  • Advice
    Aspect가 실행되는 구체적인 동작을 정의한 것으로 Join Point에서 어떤 부가적인 작업을 수행할지 지정하는 코드를 의미한다. Advice는 다양한 시점에 실행될 수 있다.
  • Pointcut
    Advice를 적용할 Join Point를 정의하는 표현식
    이다.
    어떤 메서드에서 부가적인 기능이 실행될지 지정할 때 Pointcut을 사용된다.
    보통 패키지 경로, 메서드 이름 패턴, 특정 클래스에 기반하여 Pointcut을 설정한다.
  • Target
    Aspect가 적용되는 대상 객체를 말한다. Target 객체는 Join Point에서 Aspect에 의해 부가적인 기능이 적용된다.
  • Proxy
    Target 객체를 감싸는 대리 객체로 Spring AOP에서는 주로 JDK 동적 프록시 또는 CGLIB 프록시를 사용한다.
  • Weaving
    Aspect와 Target 객체를 결합하는 과정으로 Spring AOP는 런타임 Weaving을 사용한다.

Spring AOP란

Spring AOP는 프록시 패턴이라는 디자인 패턴을 사용해서 AOP 효과를 낸다.
프록시 패턴을 사용하면 어떤 기능을 추가하려 할 때 기존 코드를 변경하지 않고 기능을 추가할 수 있다.


어떤 클래스가 Spring AOP의 대상이라면 그 기존 클래스의 빈이 만들어질 때 Spring AOP가 프록시(기능이 추가된 클래스)를 자동으로 만들고 원본 클래스 대신 프록시를 빈으로 등록한다. 

그리고 원본 클래스가 사용되는 지점에서 프록시를 대신 사용한다.


Proxy / Proxy Pattern

Proxy는 실제 Target의 기능을 수행하면서 기능을 확장하거나 추가하는 실제 객체(Object)를 의미한다.
Proxy Pattern은 Client가 Target에 접근하는 방식을 변경해 주는 역할을 한다.

호출자(클라이언트)에서 타겟을 호출하게 되면 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 타겟 메서드 실행 전에 선처리, 타겟 메서드 실행 후, 후처리를 실행시키도록 구성되어 있습니다.

Spring AOP에서는 런타임시에 Weaving을 통해서 프록시 객체를 생성하게 됩니다.

 

프록시 패턴에 대해서는 [Spring/개념] - 프록시 패턴(Proxy Pattern) 포스팅을 참고 바란다.


Dynamic Proxy(JDK Dynamic Proxy , CGLIB Proxy)

정적으로 프록시를 만들어서 AOP를 구현하는 것이 아니라 프록시를 조건에 따라 자동으로 만들어주는 Dynamic Proxy를 이용한다. Dynamic Proxy에는 JDK Dynamic Proxy와 CGLIB가 있다.

 

JDK Dynamic Proxy반드시 Interface가 정의되어있어야 하고, Interface에 대한 명세를 기준으로 Proxy를 생성한다.

 

CGLIB Proxy는 순수 Java JDK 라이브러리를 이용하는 것이 아닌 CGLIB라는 외부 라이브러리를 추가해야만 사용할 수 있다.  Interface가 없어도 Proxy를 생성할 수 있다. CGLIB Proxy는 Target Class를 상속받아 생성된다. 그렇기 때문에 개발자는 Proxy를 생성하기 위해 굳이 Interface를 만들어야 하는 수고를 덜 수 있다.

하지만, 상속을 이용하는 만큼 final이나 private과 같이 상속에 대해 Override를 지원하지 않는 경우 Proxy에서 해당 메서드에 대한 Aspect를 적용할 수 없다는 단점이 있다.

 

Target Object가 interface를 구현하였다면 JDK Proxy가 사용되고 Target Object가 interface를 구현하지 않았다면 CGLIB Proxy가 사용된다.

 


AOP Logging 적용

@Slf4j
@Aspect
@Component
public class AdviceLogging {
    
    @Before("execution(* com.devlog..*.*(..)) " 
            + "&& !execution(* com.devlog.common.jwt..*.*(..)) "
    )
    public void logging(JoinPoint joinPoint) {
        log.info("# method: {}", joinPoint.getSignature());
    }
    
    @AfterReturning(pointcut = "execution(* com.devlog..*.*(..)) " 
                            + "&& !bean(*Mapper) "
                            + "&& !execution(* com.devlog.common.jwt..*.*(..)) "
    )
    public void loggingAfterReturning(JoinPoint joinPoint) {
        log.info("# method: {}", joinPoint.getSignature());
    }
}

 

 

  • Logging에 대한 공통관심사를 분리시켜 업무 개발자는 비즈니스에 집중할 수 있는 구조가 되었다.

반응형

'Spring > 개념' 카테고리의 다른 글

[JAVA] Multi-Thread 사용법  (0) 2022.03.02
[Spring] IoC 컨테이너 / Bean  (0) 2021.10.14
@Autowired 인터페이스 사용이유  (0) 2021.10.07
@Autowired 사용법  (0) 2021.10.06
[Spring] component-scan 사용이유  (0) 2021.10.05

관련글 더보기

댓글 영역

>