자바칩

[Spring] AOP 개념 본문

Study/Spring

[Spring] AOP 개념

아기제이 2024. 6. 2. 16:56
728x90

AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

AOP는 프로그램의 여러 부분에 걸쳐 공통적으로 사용되는 기능을 모듈화하는 프로그래밍 패러다임이다. 예를 들어, 로깅, 보안, 트랜잭션 관리 등의 기능은 다양한 클래스와 메소드에 걸쳐 필요할 수 있다. AOP는 이러한 공통 기능을 하나의 모듈로 분리하여 코드의 중복을 줄이고 유지 보수를 용이하게 한다.

 

AOP의 목적

OOP와 이름이 비슷하여 상반된 개념 같지만, 관점 지향 프로그래밍은 객체 지향 프로그래밍을 보완하기 위해 쓰인다. 기존 객체(Object) 지향은 목적에 따라 클래스를 만들고 객체를 만들었다. 따라서 핵심 비즈니스 로직이든, 부가 기능의 로직이든 하나의 객체로 분리하는데 그치고, 그래서 이 기능들을 어떻게 바라보고 나눠쓸지에 대한 정의가 부족하다는 단점이 있다.

 

보통 비즈니스 웹 애플리케이션이라면 사업에 핵심적인 핵심 비즈니스 로직이 있고, 애플리케이션 전체를 관통하는 부가 기능 로직이 있다. 이를 횡단 관심사(cross-cutting concerns)라고 한다. 종류는 로깅, 보안, 트랜젝션이 있다.

 

횡단 관심사의 코드를 핵심 비즈니스 로직의 코드와 분리하여, 코드의 간결성을 높이고 변경에 유연함과 무한한 확장이 가능하도록 하는 것이 AOP의 목적이다.

 

다양한 AOP 적용 방식

AOP를 적용하는 방식은 여러 가지가 있다.

 

1. 컴파일 시점 적용

컴파일 시점 적용 방식은 AspectJ 컴파일러가 일반 .java 파일을 컴파일할 때 부가 기능을 넣어서 .class 파일로 컴파일해주는 것을 의미한다. 이 동작을 Aspect와 실제 코드를 연결하는 위빙(weaving)이라고 부른다.

 

2. 클래스 로딩 시점 적용

JVM 내 클래스로더에 .class 파일을 올리는 시점에 바이트 코드를 조작해 부가 기능 로직을 추가하는 방식이다.

 

3. 런타임 시점 적용

컴파일, 클래스 로딩, main() 메소드의 실행 이후에 자바가 제공하는 범위 내에 부가 기능을 적용하는 방식이다. 이미 런타임 중이라 코드를 조작하기 어려워 스프링, 컨테이너, DI, 빈 등 여러 개념과 기능을 총동원하여 프록시를 통해 부가 기능을 적용하는 방식이다.

프록시는 메소드 실행 시점에만 다음 타겟을 호출할 수 있기 때문에, 런타임 시점에 부가 기능을 적용하는 방식은 메소드의 실행 지점으로 제한된다.

 

AOP의 주요 개념

  • Aspect(관점): 공통 기능을 모듈화한 것을 말한다. 예를 들어, 로깅 기능을 구현한 모듈이 Aspect이다.
  • Join point(조인 포인트): Aspect를 적용할 수 있는 지점을 말한다. 자바에서는 보통 메소드 호출 시점이 조인 포인트가 된다.
  • Advice(어드바이스): Aspect에 포함된 실제 구현 코드를 말한다. 즉, 조인 포인트에서 실행될 코드를 정의한다.
    • Before Advice: 메소드 실행 전에 실행된다.
    • After Advice: 메소드 실행 후에 실행된다.
    • Around Advice: 메소드 실행 전후 또는 메소드 실행을 대체하여 실행된다.
    • After Returning Advice: 메소드가 정상적으로 실행된 후에 실행된다.
    • After Throwing Advice: 메소드 실행 중 예외가 발생한 후에 실행된다.
  • Pointcut(포인트컷): 어드바이스가 적용될 조인 포인트를 선별한다. 예를 들어, 특정 메소드나 클래스에만 어드바이스를 적용할 수 있다.
  • weaving(위빙): 어드바이스를 실제 코드에 적용하는 과정이다. 이는 컴파일 타임, 클래스 로딩 타임, 런타임에 이루어질 수 있다.

 

Spring AOP

 

Spring AOP는 런타임 시점에 적용하는 방식을 사용한다. 이유는 컴파일 시점과 클래스 로딩 시점에 적용하려면 별도의 컴파일러와 클래스로더 조작기를 써야 하는데, 이것을 정하고 사용 및 유지하는 과정이 매우 어렵고 복잡하기 때문이다. Spring Framework는 AOP를 지원하며, 주로 선언적 방식으로 사용된다. Spring AOP는 프록시 기반으로 동작하며, 메소드 실행 전후에 어드바이스를 적용한다. 다음은 Spring AOP를 사용하는 예시이다.

 

예제: 스프링 AOP를 이용한 로깅

 

1. 의존성 추가 (Maven)

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

 

2. 커스텀 어노테이션 정의

 
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogExecutionTime {
       
    }
 

 

3. Aspect 정의

 
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    // @Around 어드바이스를 사용하여
    // @LogExecutionTime 어노테이션이 붙은 메소드의 실행 시간을 측정하고 로그를 출력
    public class LoggingAspect {    
        @Around("@annotation(LogExecutionTime)")
        public Object logExecutionTime(ProceedingJoinPoint joinpoint) throws Throwable {
            long start = System.currentTimeMillis();

            Object proceed = joinPoint.proceed();

            long executionTime = System.currentTimeMillis() - start;

            System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
            return proceed;
        }
    }
 

 

4. 어노테이션 사용

 
    import org.springframework.stereotype.Service;

    @Service
    public class MyService {  
        @LogExecutionTime    // 메서드 실행 시간을 로깅하는 데 사용
        // @LogExecutionTime 어노테이션을 사용하여 로깅 어드바이스가 적용
        public void serve() throws InterruptedException {
            Thread.sleep(2000);
        }
    }
 

 

이와 같이, AOP를 사용하면 공통 기능을 개별 비즈니스 로직에서 분리하여 코드의 중복을 줄이고 유지 보수를 쉽게 할 수 있다.

 

 

아래 링크의 블로그를 보고 AOP 개념을 공부하는 데에 도움이 많이 되었다.

https://velog.io/@kai6666/Spring-Spring-AOP-%EA%B0%9C%EB%85%90#-%EB%8B%A4%EC%96%91%ED%95%9C-aop-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EC%8B%9D

 

[Spring] Spring AOP 개념

AOP는 관점(Aspect)지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다. 관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것이다.OOP와 이름

velog.io