사이드 프로젝트/순수 자바로 스프링 만들기

순수 자바로 Spring AOP 프레임워크 만들기

마늘냄새폴폴 2025. 6. 10. 23:45

이번 포스팅에선 Spring AOP를 깊이있게 파헤쳐보고 정리해보도록 하겠습니다. 코드는 깃허브를 참고해주시면 감사하겠습니다. 코드는 웬만하면 적지 않을 예정입니다. 제 블로그 포스팅은 기본적으로 코드를 되도록 적지 않는데 그 이유는 코드가 많아지면 설명해야할게 많아지고 그럼 가독성이 떨어진다고 생각하기 때문입니다.

 

또한, 저도 공부하면서 포스팅을 수백개 봤지만 사실 코드를 잘 안봅니다... 그리고 깃허브를 들어가서 실제 코드를 보면 아시겠지만 변수명과 함수명이 실제 스프링 프로젝트와 다른 부분이 있습니다. 그 이유는 

 

  1. 실제 스프링 프로젝트는 훨씬 더 복잡한 계층 구조와 다양한 팩토리 클래스를 가지고 있습니다. 그래서 제 프로젝트는 최대한 가볍게 만들기 위해서 변수명을 조정했습니다. 
  2. 사실 코드는 별로 중요하지 않다고 생각하고 흐름만 공부하면 좋겠다고 생각했습니다. 
  3. AI의 도움을 받긴 했지만 커서와 같은 AI는 도움만 주었고 실제 코드 작성은 제가 하는 편입니다. 그 중에서 AI가 적어준 변수명보다 제가 이해하기 편한 변수명을 사용한 것도 있습니다. 

https://github.com/garlicpollpoll/springlite

 

 

본격적으로 시작해보도록 하겠습니다. 

 

순수 자바로 Spring AOP 개발하기

AOP (Aspect Oriented Programming) 가 생각보다 볼륨이 매우 큰 프레임워크인 것을 이번에 개발하면서 알게 되었습니다. AOP의 가장 큰 부분을 차지하는 것은 @Aspect가 붙어있는 클래스를 프록시로 만들어 실제 빈이 실행되는 것이 아니라 프록시가 실행되도록 하는 것입니다. 

보통 위의 그림처럼 되어있는 것이 일반적이라면 AOP는

 

 

이렇게 프록시가 앞에서 실제 빈을 흉내내듯이 동작하여 우리가 원하는 동작을 수행할 수 있게 합니다. 

 

이에 관한 자세한 내용은 아래의 링크에 기술되어있습니다. 아래의 링크를 참고해주세요!

 

https://coding-review.tistory.com/426

 

프록시패턴, 데코레이터 패턴

이번 포스팅에는 프록시 패턴과 데코레이터 패턴에 대해서 알아보겠습니다. 뜬금없이 왜 프록시 패턴과 데코레이터 패턴을 공부했냐면 제가 AOP를 공부했기 때문입니다. 스프링 AOP에서 사용하

coding-review.tistory.com

 

AOP의 구조

AOP는 크게 여섯개의 구조로 나눠져있습니다. 

 

  • ProxyFactory : 프록시 팩토리는 만들어진 프록시가 어떻게 행동할지 정하는 AOP의 심장입니다. 여기서 만들어진 프록시들의 행동강령이 정해지는 것이죠. 
  • AspectScanner : @Aspect가 붙어있는 클래스를 스캔하는 용도로 사용되는 클래스입니다. 
  • JoinPoint : JoinPoint는 AOP에서 메서드 실행 지점 (Join Point) 이며 AOP를 사용해본 분들은 아시겠지만 JoinPoint를 메서드 인자값으로 받아서 내가 원하는 시점에 메서드를 실행시키게 되는데 이 때 사용하게 됩니다. 
  • Metadata : 메타데이터는 AdviceMetadata와 AspectMetadata가 있고 이 두개 모두 AspectScanner때 스캔되고 메타데이터로 등록됩니다. 
  • PointcutMatcher : PointcutMatcher는 우리가 AOP에서 사용하는 pointcut 문법을 해독하기위해 사용됩니다. 
  • InvocationHandler : InvocationHandler는 어드바이저가 실행되는 순서인 어드바이저 체인을 위해 사용됩니다. 

 

이제 구조는 알았으니 흐름도를 알아보도록 하겠습니다. 

 

AOP의 흐름

AOP의 흐름을 하나하나 뜯어보면 정말 복잡하지만 제가 이해하기 편하게 나름대로 정리해서 포스팅해보려고 합니다. 

 

  1. AnnotationApplicationContext에서 @Aspect가 붙은 클래스를 찾아내서 빈으로 등록합니다. 
  2. AspectScanner에서 어드바이저들을 검색해서 메타데이터로 저장합니다. 
  3. ApplicationContext에서 빈으로 등록될 때 createBean을 호출하고 여기서 @Aspect가 붙었다면 프록시를 생성합니다. 
  4. 실제로 빈이 실행될 때 InvocationHandler에서 어드바이저 순서대로 실행됩니다. 

 

AOP의 흐름은 이정도로 정리할 수 있을 것 같습니다. 

 

AOP의 어드바이저 순서

어드바이저는 @Before, @Around, @After, @AfterReturning, @AfterThrowing 이렇게 다섯개가 있는데 실행 순서는 다음과 같습니다. 

 

  1. @Before 실행
  2. @Around 실행 (proceed 실행 전)
  3. 메서드 실행
  4. @AfterReturning / @AfterThrowing (이 두개는 메서드가 실행되고 정상작동한다면 @AfterReturning, 에러가 발생한다면 @AfterThrowing이 실행됩니다.)
  5. @Around 실행 (proceed 실행 후)

 

마치며

이번 포스팅에는 코드는 생략하도록 하겠습니다. 코드가 너무 많아서 여기에 적기시작하면 끝이 없을 것 같습니다. 하지만 이번에 개발한 AOP를 하나하나 뜯어보면서 정말 많은 공부가 된 것 같습니다. 

 

오늘 포스팅을 끝내고 AOP 프레임워크의 아키텍처를 그려보면서 다시 복습해서 아키텍처 프로젝트에 업로드할 예정입니다. 

 

혹시 순수 자바로 Spring 프레임워크를 만들어보고 싶으신 분들은 cursor에 context7이라는 mcp붙여서 해보시면 편하게 라이트버전으로 만들어주니까 개발된거 하나씩 뜯어보면서 공부하면 많은 도움이 될 것 같습니다. 

 

이번 포스팅은 여기서 마무리 짓도록 하겠습니다. 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루되세요~