[spring] AOP란 무엇인가요?

orca·2023년 11월 21일
0

Spring

목록 보기
12/13

AOP는 Aspect 단위로 코드를 나누는 것을 의미합니다. 서비스 로직에서 로깅이나 트랜잭션은 공통적인 기능입니다. 이러한 공통적으로 기능하는 문제를 모듈화하는 것이 cross-cutting 입니다.

Spring AOP

AOP 용어

  • Aspect : 공통적으로 기능하는 문제에 대한 모듈화
  • Join point : Aspect 의 대상이 되는 특정 메서드
  • Point Cut : Join point 에 대한 지칭
    • ex) @After @Before @AfterReturning @Around
  • Advice : Join point 에서 Aspect가 실행할 조치

로깅 Aspect 구현

@Transactional 은 대표적인 AOP의 활용임
@Transactional과 동일하게 메서드 앞 뒤로, 어노테이션을 붙여 작동하는 로깅 Aspect를 구현해보자

1. 기본 설정

implementation 'org.aspectj:aspectjweaver'
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
  • @EnableAspectJAutoProxy spring에 AOP 프록시를 허용할 것임을 알려줌

2. 어노테이션 만들기

Join Point를 나타내기 위한 어노테이션을 만들자

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface CustomLogger {
}
  • @Target(ElementType.METHOD) : 메소드에 붙이는 어노테이션임

  • @Retention(RetentionPolicy.CLASS) : 바이트 코드에 기록됨

    💬 아마도 Spring AOP 프록시가 표준 JDK Dynamic Proxy라서 바이트 코드까지만 기록되도 되는 것 같다.

3. 로깅 Aspect 만들기

@Slf4j
@Aspect
@Component
public class LoggingAspect {
    @Around("@annotation(CustomLogger)")
    private void logger(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        log.info(joinPoint.getTarget() + " call " + methodName);
        joinPoint.proceed();
        log.info(joinPoint.getTarget()  + " end " + methodName);
    }
}
  • @Aspect : Aspect 클래스임
  • @Component : 빈에 등록하는 클래스임
  • @Around : Join Point 앞 뒤로 실행되는 모듈임
    • @annotation(CustomLogger) : @CustomLogger를 붙인 메서드는 다 Join Point임
  • joinPoint.proceed(); : Join Point가 실행되는 시점을 지정함

4. 서비스 코드에 적용

로깅 Aspect를 서비스 코드에 적용해보자

@Slf4j
@Component
public class SomeService {
    @CustomLogger
    public void someLogic() throws SQLException {
        log.info("do biz logic");
    }
}
  • @CustomLogger : 아까 생성한 어노테이션을 붙여 Join Point임을 나타냄

5. 결과

someLogic() 호출시 아래와 같이 메서드 앞뒤로 로깅 Aspect가 작용하는 것을 확인할 수 있다.

@SpringBootApplication
public class SomeApplication implements ApplicationRunner {

    @Autowired
    SomeService someService;

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

    @Override
    public void run(ApplicationArguments args) throws Exception {
        someService.someLogic();
    }
}

Aspect Oriented Programming with Spring
Kotlin으로 Spring AOP 극복하기!

0개의 댓글