kmsoon 2024. 6. 14. 16:13

Aspect-Oriented Programming (AOP, 관점 지향 프로그래밍)은 소프트웨어 개발의 주요 관심사를 모듈화하는 프로그래밍 패러다임입니다. 주 관심사 외의 횡단 관심사(로깅, 보안, 트랜잭션 관리 등)를 효과적으로 분리하여 코드의 중복을 줄이고 유지보수성을 높이는 데 중점을 둡니다.

 

 

 

AOP의 기본 개념

 

  1. 횡단 관심사(Cross-Cutting Concerns):
    • 애플리케이션의 핵심 로직에 영향을 주지 않으면서 여러 모듈에 공통적으로 적용되는 기능입니다. 예를 들어, 로깅, 보안, 트랜잭션 관리 등이 있습니다.
  2. Aspect:
    • 횡단 관심사를 모듈화한 것입니다. Aspect는 Advice와 Pointcut을 포함합니다.
  3. Advice:
    • 실제로 수행되는 코드를 의미합니다. Advice는 특정 시점에 실행될 코드를 정의합니다. 주로 Before, After, Around로 구분됩니다.
  4. Pointcut:
    • Advice가 적용될 지점을 정의합니다. 메소드 호출이나 객체 생성 등의 시점을 명시합니다.
  5. Join Point:
    • Advice가 적용될 수 있는 모든 지점입니다. 메소드 호출, 객체 생성 등이 Join Point가 될 수 있습니다.
  6. Weaving:
    • Aspect를 애플리케이션 코드에 적용하는 과정입니다. 컴파일 시, 로드 시, 런타임 시에 적용될 수 있습니다.

 

 

 

 

AOP의 동작 방식

스프링 AOP 예제

스프링 프레임워크에서 AOP를 사용하는 예제를 통해 이해를 돕겠습니다.

1. 의존성 추가

먼저, build.gradle 파일에 스프링 AOP와 AspectJ 의존성을 추가합니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop'
    implementation 'org.aspectj:aspectjweaver'
}

 

 

2. Aspect 정의

Aspect를 정의하는 클래스를 작성합니다. 예를 들어, 메소드 실행 전후에 로그를 출력하는 Aspect를 작성해보겠습니다.

package com.example.demo;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Before("execution(* com.example.demo..*(..))")
    public void logBefore() {
        logger.info("A method is about to be executed");
    }

    @After("execution(* com.example.demo..*(..))")
    public void logAfter() {
        logger.info("A method has been executed");
    }

    @Around("execution(* com.example.demo..*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("Method execution start: " + joinPoint.getSignature().toShortString());
        Object result = joinPoint.proceed();
        logger.info("Method execution end: " + joinPoint.getSignature().toShortString());
        return result;
    }
}

 

 

3. 테스트용 서비스 클래스 작성

Aspect를 적용할 서비스 클래스를 작성합니다.

package com.example.demo;

import org.springframework.stereotype.Service;

@Service
public class MyService {
    public void performAction() {
        System.out.println("Performing action...");
    }
}

 

 

4. 애플리케이션 실행

이제 스프링 애플리케이션을 실행하면, MyService의 performAction 메소드가 호출될 때 Aspect가 적용되어 로그가 출력됩니다.

package com.example.demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner run(MyService myService) {
        return args -> {
            myService.performAction();
        };
    }
}

 

 

AOP는 애플리케이션의 비즈니스 로직과 무관한 횡단 관심사를 분리하여 모듈화하는 프로그래밍 패러다임입니다. 스프링 AOP와 같은 프레임워크를 사용하면 횡단 관심사를 Aspect로 정의하고, Pointcut을 통해 적용 지점을 명시하여 코드의 중복을 줄이고 유지보수성을 높일 수 있습니다.