본문 바로가기

Spring

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

이번에는 스프링의 핵심 기능 중 하나인 AOP에 대해서 알아보려고한다.

AOP란?

AOP란 OOP(객체지향프로그래밍)의 단점(상속, 위임을통한 구현)을 극복해서 나온 기법으로 공통기능을 핵심로직에 삽입하는 형식의 기법이다. AOP기법에서는 공통기능을 직접 호출하지않고 AOP라이브러리가 알맞게 삽입해준다.

AOP의 주요용어

  • Advice - 언제 공통기능을 핵심로직에 적용할 지를 나타낸다. ex) 메서드 호출 전(언제)에 트랜잭션 시작기능(공통기능)을 적용한다.
  • Joinpoint - Advice를 적용 가능한 지점을 의미한다. 메서드 호출, 필드 값 변경등이 해당된다.
  • Pointcut - Joinpoint의 부분집합으로 실제로 Advice가 적용되는 Joinpoint를 나타낸다. AspectJ를 통해 정의한다.
  • Weaving - Advice를 핵심로직코드에 적용하는 것을 나타낸다. 즉 공통기능을 핵심 로직코드에 삽입하는 것이다.
  • Aspect - 여러 객체에 적용되는 공통기능(로깅, 트랜잭션, 보안)을 뜻한다.

스프링에서는 자체적으로 프록시 기반의 AOP를 제공하고있다. 따라서, 스프링 AOP는 메서드 호출 Joinpoint만을 제공해준다. 

구현 가능한 Advice의 종류

  • Before Adivce - 메서드 호출 전에 공통기능을 실행
  • After Returning Advice - 대상 객체의 메서드가 익셉션 없이 실행 된 후 공통기능을 실행
  • After Throwing Advice - 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우 공통기능을 실행
  • After Advice - 익셉션이 발생된 여부와 관계 없이 메서드가 실행 된 후에 공통기능을 실행(finally 구문)
  • Around Advice - 대상 객체의 메서드 실행 전과 후, 익셉션 발생 시점에 공통기능을 실행

XML설정을 통한 AOP적용은 <aop:config>, <aop:aspect>, <aop:pointcut>, <aop:around>를 통해 적용한다.


<aop:config>
	<aop:aspect id = "aspect1" ref = "빈이름">
    	<aop:pointcut id = "publicMethod" expression = "public * com.flyscanner.my..*(..))"/>
        <aop:around pointcut-ref = "publicMethod" method = "trace"/>
    <aop:asepect/>
<aop:config/>


@Aspect 애노테이션을 통해서도 AOP를 설정할 수 있다. @Aspect 애노테이션을 사용하려면 먼저 XML설정에서
<aop:aspectj-autoproxy/>를 설정해야한다. 


@Aspect
public class profiler2 {
	@Pointcut("execution(public * main.controller..*(..))")
	private void publicMethod() {
		
	}
	
	@Around("publicMethod")
	public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
		String signatureString = joinPoint.getSignature().toShortString();
		System.out.println(signatureString + "실행 전");
		long start = System.currentTimeMillis();
		try {
			Object result = joinPoint.proceed();
			return result;
		}finally {
			long finish = System.currentTimeMillis();
			System.out.println(signatureString + "실행 후");
			System.out.println("실행 시간 " + (finish-start) + "ms");
		}
	}
}

JoinPoint 파라미터는 항상 첫번째로 사용해야한다. 

하나의 JoinPoint에 여러개의 Advice가 지정될 경우 order속성이나 @Order를 통해서 순서를 지정할 수 있다.