[Spring] AOP

유시준·2021년 11월 9일
0
post-custom-banner

AOP란?

AOP(Aspect Oriented Programming) : 관점 지향 프로그래밍

  • DI는 애플리케이션 모듈들간의 결합도를 낮춤
  • AOP는 애플리케이션 전체에 걸쳐 사용되는 기능을 재사용하도록 지원
  • 프로젝트 구조를 바라보는 관점을 바꿔서 보는 것
  • 비즈니스 로직이외 인프라 로직(권한체크,시간체크, 트랜잭션)을 처리하기 위한 모듈

AOP의 특징

  • 프록시 패턴을 이용해 AOP 효과를 낸다.

  • 클래스가 AOP의 대상이라면

AOP 용어

  • Target - 어떤 대상에 기능을 부여할 것 인가

  • Advice - 어떤 부가기능?(before,after 등등)

  • Join point - 어디에 적용할 것 인가? (메서드,생성자 등등)

  • Point cut - 실제 advice가 적용될 지점, Spring AOP에서는 advice가 적용될 메소드를 선정

왜 AOP를 쓸까?

기존의 회원유저와 관련된 서비스 클래스가 아래와 같이 있다고 해보자.

class MemberServiceImpl{
	public void join(MemberDto memberDto){
    	memberRepository.join(memberDto);
    }
    
    public void modify(MemberDto memberDto){
    	memberRepository.modify(memberDto);
    }
    
    //여러 서비스 메소드
}

각 메소드의 실행시간을 측정하고 싶을때 아래와 같이 메소드에 시간측정을 해주는 코드를 작성하면된다.

class MemberServiceImpl{
    @Override
	public void join(MemberDto memberDto){
    	long startTime = System.currentTimeMillis();
    	memberRepository.join(memberDto);
        log.info(System.currentTimeMillis() - startTime);
    }
    @Override
    public void modify(MemberDto memberDto){
        long startTime = System.currentTimeMillis();
    	memberRepository.modify(memberDto);
        log.info(System.currentTimeMillis() - startTime);
    }
    
    //여러 서비스 메소드
}

모든 클래스에 모든 메소드에 시간측정 코드를 넣는다면 아마 매우 귀찮을 것 이다.
그래서 AOP를 이용한다.
의존성을 추가해준뒤 AOP @Aspect 어노테이션을 붙여 Aspect를 나타내는 클래스라는 것을 명시한뒤 Component를 붙여 스프링 빈으로 등록한다. @Around어노테이션으로

org.springframework.boot
spring-boot-starter-aop

@Component //등록
@Aspect //aspect
public class PerfAspect {

  @Around("@annotation(TimeLogging)") //point cut
  public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
    long start = System.currentTimeMillis();
    Object retVal = pjp.proceed(); // 메서드 호출 자체를 감쌈
    System.out.println(System.currentTimeMillis() - start);
    return retVal;
  }
}

class MemberServiceImpl{
	@TimeLogging
	@Override
	public void join(MemberDto memberDto){
    	long startTime = System.currentTimeMillis();
    	memberRepository.join(memberDto);
        log.info(System.currentTimeMillis() - startTime);
    }
    
    @TimeLogging
	@Override
    public void modify(MemberDto memberDto){
        long startTime = System.currentTimeMillis();
    	memberRepository.modify(memberDto);
        log.info(System.currentTimeMillis() - startTime);
    }
    
    //여러 서비스 메소드
}

AOP 어노테이션

  • @Before (메소호출 이전) : 타겟 메소드가 호출되기 전에 어드바이스 기능을 수행

  • @After (메소드호출 이후) : 타겟 메소드가 종료되면 어드바이스 기능을 수행

  • @AfterReturning (실행 성공 후) : 타겟 메소드가 종료 후 어드바이스 기능을 수행

  • @AfterThrowing (예외 발생 후) : 타겟 메소드가 예외를 던지면 어드바이스 기능을 수행

  • @Around (메소드 호출 전후) : 타겟 메소드가 호출되기 전후에 어드바이스 기능을 수행

profile
금꽁치's Blog
post-custom-banner

0개의 댓글