Spring AOP

o_z·2024년 3월 20일
post-thumbnail

AOP (Aspect Oriented Programming)

OOP(Object Oriented Programming)이 객체지향 프로그래밍이었다면, AOP는 객체 간 관계를 지향하는 프로그래밍이다. 기능들 중 공통으로 적용되는 관심 사항과 핵심 관심 사항을 분리하여 구현하는 프로그래밍 패러다임이다. 공통 관심 사항을 분리해서 모듈화 하고, 필요한 곳에서 주입하여 사용한다.

공통 관심 사항

개발하면서 공통적으로 사용되는 기능들에 대한 관심 사항이다. 보통 비즈니스 로직은 아니고 보안, 로깅, 예외 처리 등이 포함된다. 이러한 관심사는 여러 계층에서 사용되며 코드에서 중복되어 나타난다.
ex) 각 트랜잭션 별 걸리는 시간을 재는 기능, 회원만 서비스에 접속 할 수 있도록 제한하는 기능 등

핵심 관심 사항

비즈니스 로직, 즉 주 목적에 대한 핵심 로직에 대한 관심 사항을 의미한다.
ex) 글 쓰기 기능, 친구 맺기 기능 등

AOP가 필요한 이유

애플리케이션에서 핵심 로직과 공통 로직을 분리하는 이유는 다음과 같다.
1. 코드 간결성 유지
2. 코드 재사용성 향상
3. 객체 지향 설계 원칙에 맞게 코드 구현 가능


AOP 적용하기

Spring의 기능이므로 build.gradle에 AOP 의존성을 추가한다.

implementation 'org.springframework.boot:spring-boot-starter-aop'

AOP를 적용하기 위한 애노테이션 몇가지가 있다.

  • @Aspect : AOP로 정의하는 클래스 지정
  • @Pointcut : AOP 기능을 메서드, 애노테이션 등 어디 적용할지 지점 설정
  • @Before : 메서드 실행 전
  • @After : 메서드 실행 후 (예외 발생시에도 실행 됨)
  • @AfterThrowing : 메서드에서 예외 발생 시
  • @AfterReturning : 메서드가 정상 종료 될 시
  • @Around : Before, After 모두 제어

내 프로젝트에서 여행지 추천 관련된 기능들에 대해 메서드 실행 시간을 측정하고 로깅하는 작업을 AOP로 적용해보자.

@Aspect
@Component
@Slf4j
public class TimerAop {

	@Pointcut("execution(* com.tripbros.server.recommend.service..*(..))")
	public void timer(){}

	@Around("timer()")
	public void calcExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
		StopWatch stopWatch = new StopWatch();

		stopWatch.start();
		joinPoint.proceed();
		stopWatch.stop();

		long time = stopWatch.getTotalTimeMillis();

		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		String name = signature.getMethod().getName();

		log.info("method {}'s execution time : {}",name,time);
	}
}

아래처럼 실행 시간이 정상적으로 찍힌다.

이것저것 쓸 수 있는 애노테이션이 많던데 다른 기능들도 나중에 써보고 싶다!


참고
https://ittrue.tistory.com/213
https://programforlife.tistory.com/107
https://sharonprogress.tistory.com/195

profile
트러블슈팅과 구현기를 위주로 기록합니다-

0개의 댓글