Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[스프링AOP] 스프링AOP 구현 본문

인프런/[인프런] 스프링 핵심 원리 - 고급

[스프링AOP] 스프링AOP 구현

Seung__ 2022. 1. 5. 15:27

스프링 AOP를 구현하는 일반적인 방법은 앞서 학습한 @Aspect 를 사용하는 방법이다.

 

1. AspectV1


@Slf4j
@Aspect
public class AspectV1 {

    //hello.aop.order 패키지와 하위 패키지
    @Around("execution(* hello.aop.order..*(..))")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable{
        log.info("[[log] {}", joinPoint.getSignature());
        return joinPoint.proceed(); //target호출
    }
}
  • @Around 애노테이션의 값인 execution(* hello.aop.order..*(..)) 는 포인트컷이 된다.
  • @Around 애노테이션의 메서드인 doLog 는 어드바이스( Advice )가 된다.
  • execution(* hello.aop.order..*(..)) 는 hello.aop.order 패키지와 하위 패키지( .. )를 지정하는 AspectJ 포인트컷 표현식
  • 이제 OrderService , OrderRepository 의 모든 메서드는 AOP 적용의 대상이 된다. 
  • 참고로 스프링은 프록시 방식의 AOP를 사용하므로 프록시를 통하는 메서드만 적용 대상이 된다.

 

  • 참고
스프링 AOP는 AspectJ의 문법을 차용하고, 프록시 방식의 AOP를 제공한다. 
AspectJ를 직접 사용하는 것이 아니다.
스프링 AOP를 사용할 때는 @Aspect 애노테이션을 주로 사용하는데,
이 애노테이션도 AspectJ가 제공하는 애노테이션이다.
  • 참고
@Aspect 를 포함한 org.aspectj 패키지 관련 기능은 aspectjweaver.jar 라이브러리가 제공하는 기능이다.
앞서 build.gradle 에 spring-boot-starter-aop 를 포함했는데,
이렇게 하면 스프링의 AOP 관련 기능과 함께 aspectjweaver.jar 도 함께 사용할 수 있게 의존 관계에 포함된다.
그런데 스프링에서는 AspectJ가 제공하는 애노테이션이나 관련 인터페이스만 사용하는 것이고,
실제 AspectJ가 제공하는 컴파일, 로드타임 위버 등을 사용하는 것은 아니다.
스프링은 지금까지 우리가 학습한 것 처럼 프록시 방식의 AOP를 사용한다

 

 

2. AopTest


@Slf4j
@SpringBootTest
@Import(AspectV1.class) //스프링 빈으로 등록
public class AopTest {

    @Autowired
    OrderService orderService;

    @Autowired
    OrderRepository orderRepository;

    @Test
    void aopInfo(){
        log.info("isAopProxy, orderService={}", AopUtils.isAopProxy(orderService));
        log.info("isAopProxy, orderRepository={}", AopUtils.isAopProxy(orderRepository));
    }

    @Test
    void success(){
        orderService.orderItem("itemA");
    }

    @Test
    void exception(){
        assertThatThrownBy(() -> orderService.orderItem("ex")).isInstanceOf(IllegalStateException.class);
    }

}
  • @Aspect 는 애스펙트라는 표식이지 컴포넌트 스캔이 되는 것은 아니다. 
  • 따라서 AspectV1 를 AOP로 사용하려면 스프링 빈으로 등록해야 한다.
    • Bean 을 사용해서 직접 등록
    • @Component 컴포넌트 스캔을 사용해서 자동 등록
    • @Import : 주로 설정 파일을 추가할 때 사용( @Configuration )
      @Import 는 주로 설정 파일을 추가할 때 사용하지만, 이 기능으로 스프링 빈도 등록할 수 있다.

 

  • aopInfo() 결과
    프록시가 적용되어 true가 반환되었다.
isAopProxy, orderService=true
isAopProxy, orderRepository=true
  • success() 결과
    각 메서드가 실행되기 전에 log가 찍힌 것을 볼 수 있다.
[[log] void hello.aop.order.OrderService.orderItem(String)
[orderService] 실행
[[log] String hello.aop.order.OrderRepository.save(String)
[orderRepository] 실행
  • exception() 결과
[[log] void hello.aop.order.OrderService.orderItem(String)
[orderService] 실행
[[log] String hello.aop.order.OrderRepository.save(String)
[orderRepository] 실행

 

 

3. GitHub : 220105 SpringAOP


 

GitHub - bsh6463/SpringAOP

Contribute to bsh6463/SpringAOP development by creating an account on GitHub.

github.com

 

Comments