[Spring] AOP (Aspect Oriented Programming)

한호성·2022년 11월 9일
0

글의 목적

Spring 의 큰 특징 중 하나인 관점 지향프로그래밍(AOP) 에 대해 설명하는 글 입니다.

AOP(Aspect Oriented Programming)

AOP란 ?

관점 지향은 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고, 그 관점을 기준으로 각각 모듈화 하여 사용하는 것을 의미한다.

#CF) 모듈화 : 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것을 의미
핵심적인 관점 : 적용하고자 하는 핵심 비지니스 로직
부가적인 관점 : 핵심 로직을 실행하기 위해서 행해지는, 데이터베이스 연결, 로깅, 파일 입출력을 예로 들을 수 있다.

AOP 주요 용어 및 개념

  • Aspect : 관심사들을 모듈화 한 것
  • Target : Aspect을 적용하는 곳
  • Advice : 실질적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가 기능을 담은 구현체
  • JointPoint : Advice가 적용될 위치, 끼어들 수 있는 지점 (메소드 진입 지점, 생성자 호출 시점, 필드에서 값 꺼내올 때, 등 다양한 시점에 적용가능)
  • Pointcut : JoinPoint의 상세한 스펙을 정의한 것 . 'A'란 메소드의 진입 시점에 호출할 것 과 같이 더욱 구체적으로 Advice가 실행될 지점을 정할 수 있다.

Spring AOP의 특징

  • 프록시 패턴 기반의 AOP 구현체, 프록시 객체를 쓰는 이유는 접근 제어 및 부가기능을 추가하기 위해서
  • 스프링 Bean에만 AOP 적용가능
  • 모든 AOP 기능을 제공하는 것이 아닌 스프링 IoC와 연동하여 엔터프라이즈 어플리케이션(중복 코드, 프록시 클래스 작성의 번거로움, 객체들 간 복잡도 증가)에서 가장 흔한 문제에 대한 해결책을 지원하는 것이 목적.

프록시 패턴

프록시 패턴의 목적은 기존 코드 변경 없이 접근 제어 또는 부가 기능을 추가하기 위해서이다.

       @Primary
      @Service
      public class ProxySimpleEventService implements EventService {

          @Autowired
          private SimpleEventService simpleEventService;

          @Override
          public void createEvent() {
              long begin = System.currentTimeMillis();
              simpleEventService.createEvent();
              System.out.println(System.currentTimeMillis() - begin);
          }

          @Override
          public void publishEvent() {
              long begin = System.currentTimeMillis();
              simpleEventService.publishEvent();
              System.out.println(System.currentTimeMillis() - begin);
          }

          @Override
          public void deleteEvent() {

          }
      }

위 ProxySimpleEventService는 실제 핵심 코드를 담당하는 SimpleEventService 클래스 코드를 Field로 주입 받고 있다. 즉 기존의 SimpleEventService 클래스의 코드에는 성능측정하는 코드를 작성하지 않아도 된다는 장점이 생겼다. 하지만, 이런 방식도 메소드가 많다면, 코드 중복이 일어날 것이고 , 매번 Proxy Class를 만들어야 한다는 점에서 큰 단점이 존재한다. 이것들을 해결하기 위해 나온 것이 Spring AOP이다.

AOP의 핵심 기능은 코드를 수정하지 않으면서 공통 기능의 구현을 추가하는 것이다.
공통 기능을 추가하는 방법에는 아래와 같이 3가지 방법이 존재한다.

  • 컴파일 : 자바 파일을 클래스 파일로 만들 때, 바이트 코드를 조작하여, aop 적용된 바이트 코드 생성
  • 로드 타임 : 컴파일은 원래 클래스 그대로 하고 , 클래스 로딩하는 시점에 끼워 넣는다.
  • 런타임 : a라는 클래스를 빈으로 만들 대, a라는 타입의 프록시 빈을 감싸서 만든 후, 프록시 빈이 클래스 중간에 코드를 추가해서 넣는다.

스프링 aop는 런타임에 많이 사용하며, 프록시 객체를 자동으로 만들어준다. 따라서 위에서 본 ProxySimpleEventService 클래스 처럼 상위 타입의 인터페이스를 상속 받은 클래스를 직접 구현할 필요가 없다. 단지 공통 기능을 구현한 클래스만 잘 구현하면 된다.

Reference

https://engkimbs.tistory.com/746
https://devlog-wjdrbs96.tistory.com/398

profile
개발자 지망생입니다.

0개의 댓글