[SPRING] Spring AOP

김승수·2024년 6월 19일
0

SPRING

목록 보기
19/27

⏰ 2024. 06. 19 수

✔ 스프링 이론 강의를 듣고 정리하면서 작성했습니다.

💡 목차

  1. AOP(관점 지향 프로그래밍) 란?
  2. AOP를 사용하는 이유
  3. AOP를 통해 부가 기능 모듈화
  4. AOP 동작 이해

Spring AOP - 관점 지향 프로그래밍

AOP(관점 지향 프로그래밍) 란?

  • 관점 지향 프로그래밍은 관점을 기준으로 묶어 개발하는 방식을 의미한다.

  • 관점이란 어떤 기능을 구현할 때 그 기능을 핵심 기능부가 가능으로 구분해 각각 하나의 관점으로 보는 것을 의미한다.

  • 핵심 기능 : 각 API 별 수행해야 할 비즈니스 로직이다.

  • 부가 기능: 핵심기능을 보조하는 부가적인 기능이다.

  • AOP는 어떤 로직을 기준으로 핵심 기능, 부가 기능으로 나눠서 그 기능을 기준으로 각각 모듈화하하는 것을 의미한다.

  • 모듈화란 어떤 공통된 로직이나 기능을 하나의 단위로 묶어 분리하는 것을 의미한다.

AOP를 사용하는 이유

  • 모든 핵심 기능의 Controller에 부가 기능 코드를 추가했을 때, 핵심기능이 100개에 같은 부가기능을 추가해야 한다면 100개의 같은 기능을 추가해야합니다.

  • 같은 함수 내에 핵심 기능과 부가 기능이 같이 있다면, 핵심 기능의 수정이 발생한다면 부가 기능까지 연관되어 수정해야한다.

  • 또, 부가 기능의 수정이 필요하면 핵심 기능도 수정을 해야한다.

  • 이러한 이유들로 부가 기능을 AOP를 통해 모듈화할 필요가 있다.

AOP를 통해 부가 기능 모듈화

  • 부가 기능은 핵심 기능과는 관점이 다르기 때문에 핵심 기능과 분리해서 부과 기능을 중심으소 AOP를 설계 구현 가능하다.

  • 클래스에 @Aspect 애너테이션을 달아 AOP로 설정한다.

  • @Aspect 애너테이션은 Bean으로 등록된 클래스에만 적용 가능하다.

어드바이스

  • 어드바이스 해당 AOP 부가 기능의 수행 시점을 결정한다.

  • 어드바이스 애너테이션 종류

    • @Around : '핵심기능' 수행 전과 후 (@Before + @After)
    • @Before : '핵심기능' 호출 전 (ex. Client 의 입력값 Validation 수행)
    • @After : '핵심기능' 수행 성공/실패 여부와 상관없이 언제나 동작 (try, catch 의 finally() 처럼 동작)
    • @AfterReturning : '핵심기능' 호출 성공 시 (함수의 Return 값 사용 가능)
    • @AfterThrowing : '핵심기능' 호출 실패 시. 즉, 예외 (Exception) 가 발생한 경우만 동작(ex. 예외가 발생했을 때 개발자에게 email 이나 SMS 보냄)

포인트컷

  • 포인트컷은 Expression Language의 형태로 작성한고, AOP 부가 기능의 수행 지점을 결정한다.

  • 포인트컷 Expression 형태

execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws
-pattern?)
  • ? 는 생략 가능

  • modifiers-pattern : public, private, * 등과 같은 접근 제어자

  • return-type-pattern : void, String, List, * 등과 같은 반환 값의 타입

  • declaring-type-pattern : 패키지명 + 클래스명

    • com.sparta.myselectshop.controller.* - controller 패키지의 모든 클래스에 적용
    • com.sparta.myselectshop.controller.. - controller 패키지 및 하위 패키지의 모든 클래스에 적용
  • method-name-pattern(param-pattern) : 함수 명

    • addFolders - addFolders() 함수에만 적용
    • add* - add 로 시작하는 모든 함수에 적용
  • 파라미터 패턴 (param-pattern)

    • (com.sparta.myselectshop.dto.FolderRequestDto) - FolderRequestDto 인수 (arguments) 만 적용
    • () - 인수 없음
    • (*) - 인수 1개 (타입 상관없음)
    • (..) - 인수 0~N개 (타입 상관없음)
  • @Pointcut으로 포인트컷을 선언해 재사용 가능하고 포인트컷 결합(combine)도 가능하다.

  • EX) @Pointcut 사용 예시

@Component
@Aspect
public class Aspect {
  
	@Pointcut("execution(* com.sparta.myselectshop.controller.*.*(..))")
	private void forAllController() {}
  
	@Pointcut("execution(String com.sparta.myselectshop.controller.*.*())")
  	private void forAllViewController() {}
  
	@Around("forAllContorller() && !forAllViewController()")
	public void saveRestApiLog() {
	...
	}
  
	@Around("forAllContorller()")
	public void saveAllApiLog() {
	...
	}
  
}

AOP 동작 이해

  • 개념적 이해

  • 실제 동작

  • 시퀀스 다이어그램(Sequence Diagram)

  • Spring이 프록시(가짜 혹은 대리) 객체를 중간에 삽입한다.

  • DispatcherServletProductController 입장에서는 변화가 전혀 없다.

  • 호출되는 함수의 input, output이 완전 동일합니다.

  • joinPoint.proceed()에 의해서 원래 호출하려고 했던 함수, 인수(argument) 가 전달된다.
    → createProduct(requestDto);

profile
개발하는 미어캣

0개의 댓글