[입문][7] AOP

kiteB·2021년 8월 10일
0

Spring 강의노트

목록 보기
7/24
post-thumbnail

📌 김영한 선생님의 스프링 입문 강의 강의를 들으면서 공부한 내용을 정리한 게시물입니다.


[ AOP가 필요한 상황 ]

AOP가 무엇인지 알아보기 전에 먼저 AOP가 필요한 상황부터 살펴보자!

👨🏻 : 요즘 우리 시스템이 말이야~ 너무 느린 것 같아.
모든 메소드의 호출 시간을 한 번 측정해서 보고하게.
👩🏻 : 넵..!

가장 간단한 방법은 다음과 같이 모든 메소드의 시작과 끝에 호출 시간을 초 단위로 측정하는 코드를 하나하나 작성하는 방법일 것이다.

조금 번거롭기는 하지만 결과는 잘 나오므로 아래와 같이 모든 코드에 시간 측정 로직을 추가하는 작업을 (메소드가 100개 있으면 100번) 반복하면 될 것이다.

하지만 갑자기 초 단위가 아닌 ms 단위로 바꾸라고 한다면?

👨🏻 : 초 단위로 하니까 잘 안나오네. 초 단위말고 ms 단위로 다시 바꿔서 해봐.
👩🏻 : ...😭

100개의 코드를 다시 하나하나 ms 단위로 출력하도록 바꿔야 할 것이다.

이렇게 하나하나 시간 측정 코드를 추가하는 방식의 문제점은

  • 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
  • 시간을 측정하는 로직은 공통 관심 사항이다.
  • 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지보수가 어렵다.
  • 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다.
  • 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야 한다.

이런 상황에서 필요한 것이 바로 AOP 이다!


📌 AOP가 필요한 상황

  • 모든 메소드의 호출 시간을 측정하고 싶다면?
  • 공통 관심 사항 (cross-cutting concern) vs 핵심 관심 사항(core concern)
  • 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?

[ AOP 적용 ]

  • AOP: Aspect Oriented Programming
  • 공통 관심 사항과 핵심 관심 사항을 분리하는 것


1. 시간 측정 AOP 등록

  • main/java/hello.hellospring/aop/TimeTraceAop
@Component
@Aspect
public class TimeTraceAop {

    @Around("execution(* hello.hellospring..*(..))")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {

        long start = System.currentTimeMillis();

        System.out.println("START: " + joinPoint.toString());

        try {
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("END: " + joinPoint.toString()+ " " + timeMs + "ms");
        }
    }
}
  • @Aspect를 붙여줘야 AOP를 사용할 수 있다.
  • @Around("execution(* hello.hellospring..*(..))"): hello.hellospring 패키지 하위에 모두 적용한다는 뜻

📌 참고 | SpringConfig 파일에 스프링 빈 등록

@Configuration
public class SpringConfig {
    ...
	@Bean
    public TimeTraceAop timeTraceAop() {
       return new TimeTraceAop();
    }
}

AOP 같은 경우는 @Component를 이용하는 방법보다
SpringConfig 파일에서 "이러한 AOP를 걸고 있구나!"를 쉽게 인지할 수 있도록 하는 것이 더 좋다.


HelloSpringApplication을 실행시키고 localhost:8080/members 에 접속해보면

이렇게 STARTEND가 여러 개 출력되는 것을 확인할 수 있다.

📌 추가적으로

위에서 main/javajava/hello/hellospring/HelloSpringApplication.java에 추가했던 시간 측정 코드를 없애준다.


2. AOP를 이용한 중복 코드 문제 해결

  • 회원가입, 회원 조회등 핵심 관심사항과 시간을 측정하는 공통 관심 사항분리한다.
  • 시간을 측정하는 로직을 별도의 공통 로직으로 만들었다.
  • 핵심 관심 사항을 깔끔하게 유지할 수 있다.
  • 변경이 필요하면 이 로직만 변경하면 된다.
  • 원하는 적용 대상을 선택할 수 있다.

3. 스프링의 AOP 동작 방식

  • AOP 적용 전 의존관계
    • 회원 컨트롤러와 회원 서비스는 각 스프링 빈으로 컨테이너에 등록되어 있고,
    • 회원 컨트롤러는 회원 서비스를 의존하고 있다.
  • AOP 적용 후 의존관계
    • 스프링은 회원 서비스가 스프링 빈으로 등록될 때 프록시(proxy)라는 가짜 회원 서비스를 만든다.
    • 회원 컨트롤러에서 회원 서비스가 호출될 때 실제 회원 서비스가 아닌 프록시 회원 서비스가 호출되고, joinPoint.proceed()가 호출되면 실제 회원 서비스의 메소드들이 동작한다.

4. 전체 그림

  • AOP 적용 전
  • AOP 적용 후

[ 📘 오늘의 TIL 정리 ]

  • AOP공통 관심 사항과 핵심 관심 사항을 분리하는 것이다.
  • 여러 코드에서 사용되는 공통 로직을 따로 분리하면 핵심 관심 사항을 깔끔하게 유지할 수 있으며, 유지보수도 용이하게 할 수 있다.
profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글