Spring

AOP

토마토계란 2021. 12. 22. 01:33
  • Aspect Oriented Programming. 관점 지향 프로그래밍

OOP에서 기능들이 상속 계층을 타고 세로로 내려오는 거라면, AOP는 비슷한 클래스드렝서 공통된 기능을 가로로 분리해낸다는 느낌

🤔 전문통신: 정해진 규칙을 가진 바이트 배열이 양쪽간에 오가는 통신 데이터 구조를 일일이 다 설계할 수 없으니 xml로 통신 → xml 기반의 웹 서비스 → REST API

즉 컴퓨터 통신의 종류로 전문 통신, 웹 서비스, REST API 등이 있다.

  • 별도의 proxy 함수 호출
  • reflection으로 annotation 체크
  • annotation 동작 - 실제 함수 호출 (annotation 에 따라 시점은 다를 수 있음)

이지만 스프링에서는 AOP Proxy 가 있기 때문에 별도의 proxy 함수를 구현하지 않아도 된다

스프링 컨테이너는 Bean을 주입할 때 proxy로 감싼 aspect-aware bean을 주입한다

따라서 이를 통해 메서드를 호출하면 실제로는 proxy 함수가 호출된다 (스프링에서 AOP를 구현한 방식)

따라서 @만 붙여도 동작하게 된다. proxy기반 annotation

annotation이 동작하지 않는 경우

스프링이 기존의 bean을 wrapping해서 aspect-awre bean 을 호출하도록 하기 때문에, bean 안에서 주입받은 빈의 메소드가 아닌 자기 자신의 메소드를 호출하면 pure bean 이 호출되어 annotation이 동작하지 않는다.

  • 해결 방법
    1. self-invocation하지 않도록 refactoring
    2. replace self-calls with aspect-aware proxy calls, i.e. use the statement likeAopContext라는 API를 사용함으로써 프레임워크와의 결합이 생긴다
    3. ((PartnerApiClient)AopContext.currentProxy())._getUserInfo(userCi); @EnableAspectJAutoProxy(exposeProxy = true) // Application 클래스에 이 것도 추가해주어야 함.
    4. use aspectj weaving (별도의 API가 비즈니스 로직에 들어가지 않으니 프레임워크 결합 없이 처리할 수 있어 추천하는 방법)
    5. 아예 @를 안쓰고 Programmatic한 방법으로 직접 API를 불러 사용하는 방법.

참고) Spring에서 annotation은 interface로부터는 상속되지 않고, abstract class로부터는 상속된다

물론 class에서 상속 받는 것도 @Inherited 메타 애너테이션이 붙어있는 애너테이션이어야 가능하다.

https://stackoverflow.com/questions/18585374/spring-aop-inherited-annotation-from-an-interface

단위 테스트(JUnit)에서 @RunWith을 붙여야만 Spring Test가 되는 이유

@RunWith 은 JUnit annotation이고, 다른 것은 Spring Framework 한정 meta-annotation이기 때문이다.

https://stackoverflow.com/questions/33345605/java-custom-annotation-aggregate-multiple-annotations