본문 바로가기
Java/Spring 기초

[Spring 기초] Spring 3대 요소 (2) Aspect Oriented Programming

by 개미는뚠뚠딴 2021. 9. 22.
반응형

2021.09.19 - [Java/Spring 기초] - [Spring 기초] Spring 3대 요소 (1) Inversion of Control

이전 글에 이어 이번에는 Spring 3대 요소 중 두 번째인 AOP (Aspect Oriented Programming) 에 대해서 알아보고자 한다. 
(이번 글도 백기선님의 강의 를 참고해서 정리했다.)

 

AOP 란 무엇인가 ? 


직역하자면 관점 지향 프로그래밍 인데 어떤 프로그램에서 핵심 기능이 있다면 부가적인 기능들을 분리해 분리된 기능의 관점에서 기능을 모듈화 하여 설계 및 개발하는 것이다.

핵심 기능과 부가적인 기능들이 분리되어 있기 때문에 핵심 기능의 수정 없이 쉽게 부가 기능을 붙이거나 수정할 수 있고 코드의 재사용성을 높일 수 있다.
(AOP 도 역시 Bean 객체에만 적용할 수 있다 ! Bean 객체가 궁금하다면 이전 글에 정의된 Bean 설명을 보면 좋다)

이렇게 세 개의 클래스가 있고 각 클래스의 핵심 기능 (가운데 test 블록) 외의 부가적인 기능이 모두 동일하다고 가정하자.

이때 AAA 블록의 기능이 수정된다면 method A, B, C 모두 찾아가서 수정해주어야 한다. 
그럼 너무 번거롭지 않은가 ! 

겹치는 기능을 모듈화

Class A, B, C 의 핵심적인 로직(가운데 test 블록)은 그대로 두고 겹치는 부분만 따로 빼준다면 (모듈화 시켜준다면)
Class A, B, C 는 훨씬 깔끔한 구조가 될 수 있다.

 

Class A, B, C 의 핵심적인 기능은 건들지 않고 부가적인 기능을 붙일 수 있는 것이다. 

원래의 기능은 그대로 동작하지만 코드는 훨씬 깔끔해지고 재사용성이 좋아졌다.

여기서 공통으로 적용되는 부분을 모듈화 한 것을 Aspect 라고 하며 부가 기능의 구현체를 Advice 라고 한다.
Advice 는 부가 기능이 무엇을 언제 할지에 대한 정의가 포함된다.

JoinPoint 는 실제 대상 되는 객체로 Advice 내부에서 겹치는 부가기능 외에 핵심기능을 언제 실행할지에 해당한다. 

이러한 부가 기능들을 적용할 대상들은 PointCut 에 의해 구별이 되는데 구체적으로 Advice 가 실행될 위치를 정의할 수 있다.

 

실제 예시 코드로 적용방법에 대해서 알아보자.

예시 코드 에 해당 예시 코드에 애노테이션을 추가하여 AOP 를 구현해보았다.

먼저 LogExecutionTime 이라는 애노테이션을 만들어준다.

@Target(ElementType.METHOD) // 해당 애노테이션을 어디에 적용할 것인지 => 메소드에 적용할 것이다
@Retention(RetentionPolicy.RUNTIME) // 해당 애노테이션을 언제까지 유지할 것인지 => 런타임까지 유지
public @interface LogExecutionTime {
}

그리고 실제 동작할 Advice 를 정의해준다.
해당 기능은 어떤 메소드가 동작할 때 동작 시간을 측정해주는 스톱워치 로그 기능 advice 이다.

@Component // Bean 으로 등록해야 하므로
@Aspect // Aspect Class
public class LogAspect {

	Logger logger = LoggerFactory.getLogger(LogAspect.class);

	// Around 애노테이션으로 pointcut 표시 해줌 (advice 가 적용될 위치)
	@Around("@annotation(LogExecutionTime)")
	// joinPoint => target method (LogExecutionTime 애노테이션이 붙은 method)
	public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
		// target method 실행하기 전 앞 뒤로 부가 기능을 붙여줌
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		Object proceed = joinPoint.proceed(); // target method 실행

		stopWatch.stop();
		logger.info(stopWatch.prettyPrint());

		return proceed;
	}

}

LogExecutionTime 애노테이션을 아까 만들어준 Advice 를 적용할 함수 위에 붙여준 뒤
실행을 해보면 실행 시간이 log 로 찍히는 것을 볼 수 있다.

Advice 를 적용할 함수 위에 LogExecutionTime 애노테이션을 붙여준다.

 

로그가 찍힌 모습

위 예시는 프록시 패턴으로 구현이 되었는데 핵심 기능 외에 부가적인 공통된 기능을 담고 있는 객체를 프록시 객체라고 하고 이렇게 프록시 객체를 통해 기존 코드를 건들이지 않고 부가 기능을 붙이는 패턴을 프록시 패턴이라고 한다.

 

이 밖에도 Spring 에는 @Transactional 이라는 애노테이션이 존재하는데 이 애노테이션 역시 AOP 가 적용된 사례라고 볼 수 있다. 

해당 애노테이션이 붙은 함수는 자동적으로 try catch 가 감싸져 예외가 발생하면 해당 동작이 실행되기 이전 시점으로 롤백시켜준다. 

 

이렇게 Java Spring 3대 주요 개념 중 두 번째인 Aspect Oriented Programming 의 개념에 대해서 알아보았다.
(다음 편 예고 : 다음 주요 개념 PSA)

반응형

댓글