Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

그라가승훈

[SpringBoot] - AOP 본문

Spring

[SpringBoot] - AOP

그라가승훈 2023. 10. 15. 20:19

- AOP(Aspect Oriented Programming)란?

AOP OOP 를 더욱 OOP답게 사용하도록 도와주는 개념이다.

AOP는 애플리케이션 전반에서 사용되는 기능(로그, 권한 체크, 인증, 예외처리 등)을 여러 코드에 쉽게 적용할 수 있도록 한다.

AOP 는 각 부가 기능의 관점에서 바라본 관점지향프로그래밍으로, 해당 부가 기능이 적용되어야 하는 시점을 설정하여 적용한다.

1.  AOP 용어

  • 관점(Aspect) : 공통적으로 적용될 기능을 의미, 횡단 관심사의 기능이라고도 할 수있다. 한 개 이상의 포인트컷과 어드바이스의 조합으로 만들어진다.
  • 어드바이스(Advice) : 관점의 구현체로 조인포인트에 삽입되어 동작한다. 스프링에서 사용하는 어드바이스는 동작 시점에 따라 다섯 종류로 구분된다.
  • 조인포인트(Joinpoint) : 어드바이스를 적용하는 지점을 의미한다. 스프링프레임워크에서 조인포인트는 항상 메서드 실행 단계만 가능.
  • 포인트컷(Pointcut) : 어드바이스를 적용할 조인포인트를 선별하는 과정이나 그 기능을 정의한 모듈을 의미.
  • 타깃(Target) : 어드바이스를 받을 대상을 의미.
  • 위빙(Weaving) 어드바이스를 적용하는 것을 의미. 즉, 원하는 대상에 공통코드를 삽입하는 것을 뜻한다.

- AOP 적용

컨트롤러, 서비스, 매퍼 메서드가 실행될 때 로그를 출력하는 로그 AOP 를 적용.

1. LoggerrAspect 클래스

aop 패키지 생성 후 LoggetAspect 클래스 생성.

@Component
@Aspect
@Slf4j
public class LoggerAspect {

    @Around("execution(* com.example..controller.*Controller.*(..)) || " +
            "execution(* com.example..service.*Impl.*(..)) ||" +
            "execution(* com.example..mapper.*Mapper.*(..))")
    public Object logPrint(ProceedingJoinPoint joinPoint) throws Throwable {
        String type = "";
        String name = joinPoint.getSignature().getDeclaringTypeName();

        if (name.contains("Controller")) {
            type = "Controller  \t:  ";
        } else if (name.contains("Service")) {
            type = "ServiceImpl  \t:  ";
        } else if (name.contains("Mapper")) {
            type = "Mapper  \t\t:  ";
        }
        log.debug(type + name + "." + joinPoint.getSignature().getName() + "()");
        return joinPoint.proceed();
    }
}
  • @Aspect : 어노테이션을 이용해서 AOP 설정.
  • @Around : 어노테이션으로 해당 기능이 실행될 시점, 즉 어드바이스를 정의.
    어드바이스는 다섯 종류가 있지만 여기서는 대상 메서드를 실행 전후 또는 예외 발생 시점에 사용할 수 있는 Around 를 적용했다.
  • execution : 포인트컷 표현식으로, 적용할 메서드를 명시할 때 사용.

2. 적용결과 확인

AOP 를 이용해서 공통적으로 적용할 로그 기능을 LoggerAspect 라는 외부 클래스에 정의하고, 애플리케이션의 실행 시점에 기능이 삽입되어서 빨간색으로 밑줄 친 부분에 로그가 추가되었다.


- AOP 주요 개념

1. 어드바이스

어드바이스는 관점의 구현체로 조인포인트에 삽입되어 동작하는 것을 의미.

시점에 따라 다섯 종류로 구분된다.

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

2. 포인트컷

어드바이스를 적용할 조인포인트를 선별하는 과정이나 그 기능을 정의한 모듈.

정규표현식이나 AspectJ 의 문법을 이용해서 어떤 조인포인트를 사용할 것인지 결정.

 

- execution

  • 가장 대표적이고 강력한 지시자접근 제어자, 리턴타입, 타입패턴, 메서드, 파라미터 타입, 예외 타입 등을 조합해서 가장 정교한 포인트컷을 만들 수 있다.
  • * : 모든 값을 의미
  • .. : 파라미터, 메서드, 패키지 등 0개 이상을 의미

예시

execution(void select*(..)) 			// 1번
execution(* com.example.controller.*()) 	// 2번
execution(* com.example.controller.*(..)) 	// 3번
execution(* com.example..select*(*)) 		// 4번
execution(* com.example..select*(*, *)) 	// 5번
  • 1번 : 리턴 타입이 void이고, 메서드 이름이 select로 시작하고, 파라미터가 0개 이상인 메서드가 호출될 때
  • 2번 : com.example.controller 패키지 밑에 파라미터가 없는 모든 메서드가 호출될 때
  • 3번 : com.example.controller 패키지 밑에 파라미터가 0개 이상인 모든 메서드가 호출될 때
  • 4번 : com.example 패키지의 모든 하위 패키지에 있는 select로 시작하고 파라미터가 한 개인 모든 메서드가 호출될 때
  • 5번 : com.example 패키지의 모든 하위 패키지에 있는 select로 시작하고 파라미터가 두 개인 모든 메서드 호출될

- within

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

예시

within(com.example.service.boardServiceImpl) // 1번
within(com.example.service.*ServiceImpl)     // 2번
  • 1번 : com.example.service 패키지 밑에 있는 boardServiceImpl 클래스의 메서드가 호출될 때
  • 2번 : com.example.service 패키지 밑에 있는 ServiceImpl 이라는 이름으로 끝나는 메서드가 호출될 때

- bean

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

예시

bean(boardServiceImpl) // 1번
bean(*ServiceImpl)     // 2번
  • 1번 : boardServiceImpl 이라는 이름을 가진 빈의 메서드가 호출될 때
  • 2번 : ServiceImpl 이라는 이름으로 끝나는 빈의 메서드가 호출될 때
Comments