ON/실습

[Spring Boot] AOP

박도비 2023. 11. 30. 21:51
728x90

이전 강의에서는 DB접근 기술에 대해서 알아보았다. 

이번시간에는 AOP에 대해서 실습해보자.

국비학원 다니면서 잠깐 짚고 넘어갔던 부분인데 기억이 안나구나...다시 복습해보자 

 

[ Spring ] SpringAOP 이론 ⑱

🤔SpringAOP 이란 ?💭 관점 지향 프로그래밍(Aspect Oriented Programming) 일반적으로 사용하는 클래스(Service, Dao 등) 에서 중복되는 공통 코드 부분(commit, rollback, log 처리) 을 별도의 영역으로 분리해 내

jnaa.tistory.com

 

1.  AOP 가 필요한 상황

 

 

내가 회사에 가서 일을 하고 있는데 과장님이 " 도비사원 기능이 실행하는데 걸리는 시간을 측정해줘 " 라고 했을때

지금은 회원가입 및 회원조회 같은 서비스만 있는데 실무에서는 서비스가 엄청 많을 것이다. 

그걸 하나하나 다 걸리는 시간을 측정하고 있다면, 하루종일 하고 있을 것이다. 

 

@Transactional
public class MemberService {
    private final MemberRepository memberRepository;

    public  MemberService(MemberRepository memberRepository){
        this.memberRepository = memberRepository;
    }

    /**
     * 회원가입
     */
    public Long join(Member member){
        
        long start = System.currentTimeMillis();
        
        try {
            validateDuplicateMember(member);
            memberRepository.save(member);
            return member.getId();
        } finally{
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("join " + timeMs + "ms");
        }
    }

    /**
     * 전체 회원 조회
     */
    public List<Member> findMembers(){
        
        long start = System.currentTimeMillis();
        
        try {
            return memberRepository.findAll();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println(timeMs);
        }
    }
}

 

이렇게 작성해서 메소드 호출 시간을 확인 할 수 있고, 만약 그림을 그린다면 아래와 같다. 

하지만 아까도 말했듯이 이렇게 하게 된다면 유지보수가 어려울 뿐더라 모든 로직을 찾아서

위와 같이 하나하나 코드를 추가하고 변경해야한다. 

 

이럴때 우리는 공통 관심사항(cross-cutting concern)과 핵심 관심사항(core concern)으로 나눠서 분류를 해야한다. 

  • 공통 관심사항(cross-cutting concern) : 실행하는데 걸리는 시간 
  • 핵심 관심사항(core concern) : 회원가입, 회워조회 같은 비즈니스 로직 

회원 가입, 회원 조회와 같은 비즈니스 로직과 같은 경우가 핵심 관심사항이고,

이러한 기능 실행하는데 걸리는 시간을 측정하는 것과 같은 기능은 공통 관심 사항으로 분류된다. 

 

우리는 이럴 때 AOP의 필요성을 느낀다! 왜 얼마나 편하길래 ? 

 

2.  AOP 적용 

이전에는 로직들을 시간측정 로직을 메서드에 하나하나 다 붙였지만

AOP 는 시간측정로직을 구현하고 내가 원하는 곳에 적용하는 것이 바로 AOP이다. 

오? 이게 된다고 ? 그렇다면 실습을 통해 알아보자 ! 

 

 

(1) TimeTraceAop 클래스 생성

package hello.helloSpring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
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");
        }

    }
}

 

 

메서드가 AOP 기능을 할 수 있도록 @Aspect 어노테이션을 사용하고 

스프링 빈으로 등록하기 위해 @Component로 스프링 빈으로 등록 한다 ! 

 

 

이제 웹 애플리케이션을 실행해서 시간 측정이 정상적으로 동작하는지 로그를 확인해 보자.

 

회원가입 후 회원목록으로 가입된 회원 확인까지 한 로그이다. 

우리가 작성한 코드대로 START와 END가 출력된 것을 볼 수 있다. 

 

3.  AOP 동작방식

 

(1) AOP 적용 전 의존관계

: 회원 컨트롤러와 회원 서비스는 각 스프링 빈으로 컨테이너에 등록되어 있고,

  회원 컨트롤러는 회원 서비스를 의존하고 있다. 

 

(2) AOP 적용 후 의존관계

: 회원 컨트롤러에서 회원 서비스가 호출될 때 실제 회원 서비스가 아닌 프록시 회원 서비스

  호출되고, joinPoint.proceed()가 호출되면 실제 회원 서비스의 메서드들이 동작한다. 

 

(3) AOP를 적용하기 전 후의 전체 모습

@Around를 통해 프로젝트 전체 메서드에 AOP가 적용되었기 때문에

컨테이너에 스프링 빈으로 등록되는 것들이 모두 프록시와 같이 등록된 것을 확인할 수 있다. 

728x90