들어가면서.
Aspect-Oriented Programming (AOP) 란?
Spring의 AOP는 다양한 애플리케이션에서 공통적으로 발생하는 문제들을 해결하기 위해 사용됩니다. AOP는 메소드 호출 전후에 수행되는 작업(어드바이스)과 해당 메소드를 정의한 포인트컷(Pointcut)을 조합하여 프로그램의 여러 부분에서 재사용할 수 있는 기능을 제공합니다.
Spring 프레임워크에서 AOP가 사용되는 대표적인 기능은 다음과 같습니다.
Spring의 트랜잭션 관리 기능은 AOP를 기반으로 구현되어 있습니다. 스프링에서는 @Transactional
어노테이션을 사용하여 트랜잭션을 관리하며, 이 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
Spring Security는 스프링에서 제공하는 보안 처리 모듈로서, AOP를 사용하여 보안 기능을 구현합니다. 스프링 시큐리티에서는 @PreAuthorize
와 @PostAuthorize
어노테이션을 사용하여 메소드의 호출 전과 후에 보안 검사를 수행하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
Spring은 AOP를 이용하여 캐싱 처리 기능을 제공합니다. 스프링에서는 @Cacheable
, @CachePut
, @CacheEvict
등의 어노테이션을 사용하여 메소드의 결과를 캐싱하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
Spring에서는 AOP를 이용하여 로깅 처리 기능을 제공합니다. 스프링에서는 @Around
어노테이션을 사용하여 메소드의 실행 전과 후에 로깅 처리를 수행하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
Spring에서는 AOP를 이용하여 예외 처리 기능을 제공합니다. 스프링에서는 @AfterThrowing
어노테이션을 사용하여 메소드에서 예외가 발생했을 때 처리할 로직을 구현하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
Spring에서는 AOP를 이용하여 성능 모니터링 기능을 제공합니다. 스프링에서는 @Around
어노테이션을 사용하여 메소드의 실행 시간을 측정하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.
다음은 Spring AOP를 사용하여 메서드 실행 시간을 로깅하는 간단한 예제 코드입니다.
- LoggingAspect 클래스 정의
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
@Before("serviceMethods()")
public void logMethodStart() {
logger.info("Method execution started");
}
@After("serviceMethods()")
public void logMethodEnd() {
logger.info("Method execution ended");
}
}
- Service 클래스 정의
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void doSomething() throws InterruptedException {
Thread.sleep(1000);
System.out.println("Doing something...");
}
}
- Main 클래스 정의
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService service = context.getBean(MyService.class);
service.doSomething();
}
}
- AppConfig 클래스 정의
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(basePackages = "com.example")
@EnableAspectJAutoProxy
public class AppConfig {}
위 코드에서, LoggingAspect 클래스는 AOP 관련 어노테이션(@Aspect, @Before, @After, @Pointcut)을 사용하여 메서드 실행 시간을 로깅합니다. Service 클래스는 AOP를 적용받을 대상이 되는 비즈니스 로직을 구현합니다. Main 클래스는 ApplicationContext를 생성하고 Service 클래스를 불러와서 메서드를 실행합니다. AppConfig 클래스는 ApplicationContext를 생성하고, AOP를 사용하기 위해 @EnableAspectJAutoProxy 어노테이션을 사용합니다.
실행 결과는 다음과 같습니다.
Method execution started
Doing something...
Method execution ended
즉, LoggingAspect 클래스의 logMethodStart 메서드가 MyService 클래스의 doSomething 메서드 실행 전에, logMethodEnd 메서드가 실행 후에 호출되어 메서드 실행 시간을 로깅하는 것을 확인할 수 있습니다.
내저장소 바로가기 luxury515