AOP(Aspect Oriented Programming)

Gyuhan Park·2022년 9월 5일
0

spring

목록 보기
12/18

AOP를 사용하게 된 배경

코드를 짜다보니 갑자기 모든 메소드의 호출시간이 궁금해졌다(?)
그래서 메소드의 맨처음과 끝에 시간을 찍어 호출시간을 측정해봤다.
근데 1~2개면 모르겠는데 이걸 다하라고? 따로 메소드를 만들기도 복잡하고, 다 만들었는데 바꾸라하면 어캄...? 오늘은 야근이다...

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");
	} 
}
  • 메소드 호출시간 측정은 기능적인 측면에서 메소드의 핵심 기능이 아니다.
  • 시간 측정 로직은 공통 관심 사항이다.
  • 공통 관심 사항과 핵심 관심 사항이 섞여있으면 유지보수가 어렵다.

AOP란?

각각의 역할이나 책임에 따라 클래스를 분리했는데, 여러 클래스에서 반복 사용되는 코드가 있을 때 AOP를 적용할 수 있다. 즉, 공통 관심 사항을 묶어 하나의 메소드처럼 모듈화하는 것이 AOP.

=> 공통 관심 사항과 핵심 관심 사항을 분리할 수 있음.

AOP 적용 방법 2가지

1. 스프링 빈에 등록해서 사용

유지보수할 때 이 프로그램은 AOP를 사용하고 있다고 인지하기 쉬워서 좋음.

@Bean
public TimeTraceAop timeTraceAop(){
	return new TimeTraceAop();
}

2. 컴포넌트 스캔

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

@Around("execution()") : AOP를 적용시킬 메소드의 범위를 정할 수 있음.

스프링의 AOP 동작 원리

- AOP 적용 전 의존관계

controller가 service를 의존하는 관계로, controller에서 service 메소드들을 호출하여 동작한다.

- AOP 적용 후 의존관계

memberService에 AOP를 적용시키면 스프링 컨테이너가 memberService를 올릴 때, 프록시 memberService를 올린다. memberController는 가상의 객체를 의존하고 있다가 AOP가 모두 실행되고 joinPoint.proceed()하면 실제 memberService가 호출된다.

[참고] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

profile
단단한 프론트엔드 개발자가 되고 싶은

0개의 댓글