Spring

스프링 AOP

deeperog 2018. 10. 12. 17:59

AOP[Aspect Oriented Programming]


AOP는 객체를 주요 코드와 부속 코드로 분리 하여 부속코드를 모듈로 정의하여 주요코드와 엮어서 처리 하는 방법을 말합니다. 예를 들자면 주요코드는 마이페이지 코드라면 부속코드는 로그인 처리라고 볼 수 있습니다. 마이페이지는 로그인이 되어있어야 접속 할 수 있기 때문에 부속 코드로 로그인 처리가 필요합니다.



그럼 이 모듈을 어떻게 설정하고 사용할까요? 



간단히 말하자면 기존에 있는 코드에서 공통적으로 사용되는 코드를 특정 메서드로 만들어 놓고, xml에 설정해 주면 됩니다. 자세한 예제는 아래에 남기겠습니다. 모듈화외에 Spring에서 AOP를 사용하면 어떤 장점이 있을까?


1.Spring AOP 적용 시 메소드 내에 부가 기능에 관련된 코드 구현은 불필요

2.XML 파일의 설정 만으로 자동 적용

3.부가적으로 적용되는 공통 기능의 로직 변경 시에도 비즈니스 메소드의 코드는 수정할 필요가 없음


이런 장점들이 있기 때문에 스프링에서는 AOP를 사용하는걸 권장합니다.


아래는 for문으로 구현된 factorial 메서드와 재귀함수로 구현된 factorial 메서드의 속도를 비교하는 AOP 를 XML 기반의 POJO 클래스를 이용해 AOP를 구현 하는 예제입니다.

public interface Calculator {
	public long factorial(long num);    //추상 메서드
}
public class RecCalculator implements Calculator {        //재귀함수로 구현된 팩토리얼
	@Override
	public long factorial(long num) {
		if (num == 0) {
			return 1;
		} else {
			return num * factorial(num - 1);
		}
	}
}
public class CalculatorImpe implements Calculator {        // for문을 사용한 팩토리얼
	@Override
	public long factorial(long num) {
		long result = 1;
		for (long i = 1; i <= num; i++) {
			result *= i;
		}
		return result;
	}
}



그 다음 AOP를 이용하기 위해 라이브러리를 추가해야합니다. 아래의 내용을 pom.xml

태그 안에 넣어 줍니다. (편의 상 1.8.2 버전을 사용하겠습니다.

org.aspectj
aspectjweaver
1.8.2



그 뒤 Advice 클래스를 만들어 줍니다. (※Advice : 
조인 포인트에 삽입되어 동작할 수 있는 공통 관심 사항의 코드)
public class ExeTimeAspect {
	public Object measure(ProceedingJoinPoint joinPoint) throws Throwable {
		long start = System.nanoTime();
		try {
			Object result = joinPoint.proceed(); // 어드바이스가 적용된 객체의 메서드 실행
			return result;
		} finally {
			long end = System.nanoTime();
			// 실행 메서드 정보
			Signature sig = joinPoint.getSignature();
			System.out.printf("%s.%s 실행 시간 : %d ns\n", joinPoint.getTarget().getClass().getSimpleName(), sig.getName(),
					(end - start));
		}
	}
}
Signature getSignature() – 호출되는 메서드에 대한 정보를 구한다.
–String getName() – 메서드의 이름을 구함
–String toLongString() – 메서드를 완전히 표현한 문장을 구한다.
–String toShortString() – 메서드를 축약해서 표현한 문장을 구한다.




그 다음 src/main/resources에 aopConfig.xml이라는 파일을 만들어 빈객체와 Advice에 어떤 Pointcut에 적용할지 지정해줍니다.



	
	
	

	

	
	
		
			
			
			
			
		
	



마지막으로 실행을 하기 위한 Main클래스를 만들고 실행해줍니다.
public class SpringAopMain {
	public static void main(String[] args) {
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:aopConfig.xml");
		RecCalculator recCalculator = ctx.getBean("cal1", RecCalculator.class);
		long calResult1 = recCalculator.factorial(5);
		System.out.println("factorial(10) 의 결과 = " + calResult1);
		CalculatorImpe calculatorImpe = ctx.getBean("cal2", CalculatorImpe.class);
		long calResult2 = calculatorImpe.factorial(5);
		System.out.println("factorial(10) 의 결과 = " + calResult2);
	}
}






실행하면 아래와 같은 결과값이 나옵니다. AOP를 이용하면 메서드의 실행시간뿐아니라 다른 로그인이나 보안 처리 등을 모듈화 하여 더욱 쉽게 사용할 수 있습니다.