[Spring]스프링 기초 - AOP(Aspect Oriented Programming)

Inung_92·2023년 2월 12일
2

Spring

목록 보기
6/14
post-thumbnail

AOP란?

📖스프링 프레임워크의 핵심 개념 중 하나로 Aspect Oriented Programming(관점지향 프로그래밍)이다.

그렇다면 관점지향 프로그래밍은 또 무엇인가?
스프링에서는 기존 AspectJ(라이브러리)를 차용한 개념으로 간단하게 설명하면 흩어진 관심사(Cross-Cutting Concern)모듈화 할 수 있는 프로그래밍 기법이다. 이 말은 프로그램의 특정 로직을 핵심적인 관점, 부가적인 관점으로 나누어 보고 그 관점을 기준으로 각각 모듈화를 하겠다는 것이다.

예를 들어 쇼핑사이트에서 고객이 물품을 구매하거나 장바구니를 확인하는 등의 기능을 사용하려면 로그인이 되어있어야 하는데 프로그램은 해당 기능을 사용하려는 고객이 로그인이 되어있는지 여부를 계속 확인해야한다. 이 부분이 바로 부가적인 관점이자 흩어진 관심사가 되는 것이다.

흩어진 관심사는 횡단적 관점이라고 말하기도 한다. 프로그램의 기능들이 핵심 로직을 수행하기 위해 반드시 건너가야하는 하나의 횡단보도라고 생각하면 좋을 것 같다.

글로 설명하기에는 너무 추상적일 수 있으니 아래 그림을 보면서 다시 한번 위의 내용을 생각해보자.

위 그림에서 물품구매, 장바구니, 결제는 고객이 이용해야할 기능이다. 해당 기능들을 이용하기 위해서는 고객이 로그인이 되어있는 상태인지 확인이 필요하다. 이때 공통적으로 수행되면서 핵심 로직이라고는 할 수 없는 로그인 확인 기능이 부가적인 관점이자 흩어진 관심사로 볼 수 있는 것이다.

⚡️ AOP의 이점

AOP는 OOP(Object Oriented Programming)의 단점을 보완하기 위하여 스프링에서 사용된다. 그렇다면 OOP의 단점을 간략하게 알아보자.

🖥️ OOP의 단점

  • 클래스 내에 기능을 구현하는 로직을 작성하거나 직접 호출하므로 코드 수정 시 해당 기능이 포함된 모든 클래스 코드를 수정해야함.
  • 공통되며 반복된 기능을 구현하기 위해서는 개발자가 직접 클래스 내부에 코드를 작성하므로 결합도가 높다.

대표적으로 두가지만 제시를 하였지만 개발을 하다보면 이만저만 불편한게 많다. 결국은 코드가 간결하지 못하고 유지보수성이 높아진다는 것이 결론이다.

🖥️ AOP의 이점

  • 흩어진 관심사를 모듈화하여 핵심적인 비즈니스 로직에서 분리하고, 재사용이 가능하다.
  • 공통적이며 반복되는 코드를 제거할 수 있으며 흩어진 관심사가 필요한 시점을 지정이 가능하다.

AOP의 대표적인 기능은 트랜잭션 처리라고 할 수 있다. 기존 OOP를 이용할 경우 트랜잭션을 일일이 처리해줘야하는 단점이 있지만 AOP를 사용하여 흩어진 관심사로 등록하고 필요한 시점에 자동적으로 호출되도록 하는 것이다.

결론적으로 수동적이면서 물리적인 코드 배치를 하게되는 기존 OOP 방식에서 흩어진 관심사의 코드를 물리적으로 분리하고 AOP로 지정하여 능동적으로 해당 기능이 수행되도록 하는 것이다. 추가로 스프링의 핵심 개념 중 DI가 의존성을 약하게 한다데 그친다면 AOP는 의존성을 완전히 탈피하는 개념인 것이다.

⚡️ AOP의 주요 개념

이제 개념적인 부분에 대해서는 어느정도 설명을 하였으니 AOP의 주요개념에 대해서 알아보자.

  • Aspect : 흩어진 관심사를 모듈화 한 것이며 주로 부가기능(트랜잭션, 로깅 등)을 모듈화
  • Target : Aspect를 적용하는 곳(클래스, 메서드...)
  • Advice : 실질적으로 어떠한 기능을 수행해야하는지에 대한 구현체
  • JointPoint : Advice가 적용되는 위치와 끼어드는 지점
  • PointCut : JointPoint의 상세한 스펙을 정의한 것

⚡️ 스프링 AOP의 특징

다음으로 스프링 AOP의 특징에 대해서 알아보자. 참고로 AOP는 스프링에만 적용되는 특수한 개념이 아니다.

  • 프록시 패턴 기반의 AOP 구현체로 접근 제어 및 부가기능을 추가하기에 용이
  • 스프링 Bean에만 AOP를 적용가능. 즉 Bean이 지정되지 않은 객체는 적용 불가능
  • 모든 AOP 기능을 제공하지 않고 엔터프라이즈 어플리케이션에서 가장 흔하고 반복되는(중복코드, 프록시 클래스 작성의 번거로움 등)에 대한 해결책을 지원하는 것이 목적

스프링 AOP 사용방법

🖥️ 의존성 추가

스프링 @AOP를 사용하기 위해서는 의존성을 아래와 같이 추가해준다.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

🖥️ Aspect 및 Advice 적용

특정 클래스가 Aspect를 나타내는 클래스라는 것을 명시하고 스프링 Bean으로 등록

@Component //Bean으로 등록
@Aspect //관점 명시
public class Test{

	@Around("execution(*com.test..*.TestService.*(..))")
	public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
		long begin = System.currentTimeMills();
    	...생략
	}
}

@Around 어노테이션은 타겟으로 지정된 메서드를 감싸서 특정 Advice를 실행한다는 의미이다. 어노테이션 뒤의 ()안의 내용은 com.test 패키지 경로의 TestService 클래스의 모든 메서드에 해당 Aspect를 적용한다는 의미이다.
위와 같이 경로를 지정하는 방식 외에 특정 어노테이션이 붙은 포인트에 해당 Aspect를 실행할 수 있는 기능도 제공한다.

@Component
@Aspect
public class Test{

	@Around("@annotation(PerLogging)")
	public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
		long begin = System.currentTimeMills();
    	...생략
	}
}

위와 같이 ()안을 명시해주면 해당 괄호안의 어노테이션만 붙은 메서드만 Aspect가 적용된다. 이 밖에도 Aspect 실행 시점을 지정할 수 있는 어노테이션은 아래와 같다.

🖥️ Aspect 실행 시점 지정 어노테이션

  • @Before(이전) : 어드바이스 타켓 메서드가 호출되기 전에 수행
  • @After(이후) : 타켓 메서드의 결과에 관계없이 완료되면 수행
  • @AfterReturning(정상적 반환 이후) : 타겟 메서드가 성공적으로 결과값을 반한 후에 수행
  • @AfterThrowing(예외 발생 이후) : 카겟 메서드가 수행 중 예외를 던지게 되면 수행
  • @Around(메서드 실행 전후) : 어드바이스가 타켓 메서드를 감싸서 타켓 메서드 호출 전과 후에 수행

마무리

이번 게시글에서는 스프링의 AOP에 대해서 알아보았다. 아직 스프링을 많이 공부하지 못해서 개념적인 내용과 기본적인 사용에 대해서만 알아본 것이다.

내가 AOP를 이해한 것은 반복적이고 중복되는 기능을 하나의 부가적인 관점으로 식별하여 모듈화하는 것이다. 모듈화를 할 경우 재사용성이 올라가며 유지보수성도 올라간다. 또한 AOP는 물리적으로 코드를 배치하는 것이 아니라 관점을 지정하고 타겟을 설정하여 능동적으로 해당 관점이 수행되도록 해주는 것이다. 즉, 의존성 탈피를 달성할 수 있으며 관점으로 지정된 기능만을 수정하여 유지보수를 완료할 수도 있다는 어마어마한 장점이 생기는 것이다.

아직 AOP를 적용할 위치와 지점을 찾는 것에 익숙하지 않지만 전체적인 프로그램에서 부가적인 관점을 잘 추출해 낼 수 있다면 AOP의 이점을 최대한 활용하여 프로그램을 개발할 수 있을 것이다. 그때까지 많은 시행착오를 겪어봐야겠다.

그럼 이만.👊🏽

profile
서핑하는 개발자🏄🏽

0개의 댓글