SpringAopImplement_1_3

์Šคํ”„๋ง AOP ๊ตฌํ˜„ - V1

@Aspect ์‚ฌ์šฉ

์Šคํ”„๋ง AOP๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ @Aspect๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

@Slf4j
@Aspect
public class AspectV1 {

    @Around("execution(* hello.aop.order..*(..))")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("[log] {}", joinPoint.getSignature());
        return joinPoint.proceed();
    }
}
  • @Around ์–ด๋…ธํ…Œ์ด์…˜์˜ ๊ฐ’์ธ execution(* hello.aop.order..*(..))๊ฐ€ ํฌ์ธํŠธ์ปท์ด ๋œ๋‹ค.

    • hello.aop.order ํŒจํ‚ค์ง€์™€ ๊ทธ ํ•˜์œ„ํŒจํ‚ค์ง€(..)๋ฅผ ์ง€์ •ํ•˜๋Š” AspectJ ํ‘œํ˜„์‹์ด๋‹ค.

  • @Around ์–ด๋…ธํ…Œ์ด์…˜์˜ ๋ฉ”์„œ๋“œ์ธ doLog๋Š” ์–ด๋“œ๋ฐ”์ด์Šค(Advice)๊ฐ€ ๋œ๋‹ค.

@Slf4j
@SpringBootTest
@Import(AspectV1.class)//์ถ”๊ฐ€
public class AopTest {

    @Autowired OrderService orderService;
    @Autowired OrderRepository orderRepository;

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

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

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

    }
}
  • @Aspect๋Š” ์• ์ŠคํŽ™ํŠธ๋ผ๋Š” ํ‘œ์‹์ผ ๋ฟ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์ด ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. AspectV1์„ ์Šคํ”„๋ง AOP๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.

  • ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

    • @Bean ์ˆ˜๋™ ๋“ฑ๋ก

    • @Component ์ž๋™ ๋“ฑ๋ก

    • @Import ์ฃผ๋กœ ์„ค์ • ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉ(@Configuration)

  • @Import๋กœ ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ฝ˜์†” ๊ฒฐ๊ณผ

hello.aop.order.aop.AspectV1             : [log] void hello.aop.order.OrderService.orderItem(String)
hello.aop.order.OrderService             : [orderService] ์‹คํ–‰
hello.aop.order.aop.AspectV1             : [log] String hello.aop.order.OrderRepository.save(String)
hello.aop.order.OrderRepository          : [orderRepository] ์‹คํ–‰
  • joinpoint ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋‹ค.

img_1.png

์Šคํ”„๋ง AOP ๊ตฌํ˜„ - V2

ํฌ์ธํŠธ์ปท ๋ถ„๋ฆฌ

@Around์— ํฌ์ธํŠธ์ปท ํ‘œํ˜„์‹์„ ์ง์ ‘ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ @Pointcut์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ๋ณ„๋„๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

@Slf4j
@Aspect
public class AspectV2 {

    @Pointcut("execution(* hello.aop.order..*(..))")
    private void allOrder(){} //ํฌ์ธํŠธ์ปท ์‹œ๊ทธ๋‹ˆ์ฒ˜

    @Around("allOrder()")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("[log] {}", joinPoint.getSignature());
        return joinPoint.proceed();
    }
}
  • @Pointcut ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

  • ๋ฉ”์„œ๋“œ ์ด๋ฆ„๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•ฉ์ณ์„œ ํฌ์ธํŠธ์ปท ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ผ ํ•œ๋‹ค.

  • ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์€ void์—ฌ์•ผ ํ•œ๋‹ค.

  • ์ฝ”๋“œ ๋‚ด์šฉ์€ ๋น„์›Œ๋‘์–ด์•ผ ํ•œ๋‹ค.

  • ํฌ์ธํŠธ์ปท ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” allOrder()๋‹ค. ์ฃผ๋ฌธ๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ํฌ์ธํŠธ์ปท ์ด๋ผ๋Š” ๋œป์ด๋‹ค.(์ด๋ฆ„์œผ๋กœ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค.)

  • ์ ‘๊ทผ ์ œ์–ด์ž๋Š” ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด private์„ ์‚ฌ์šฉํ•˜๊ณ  public์œผ๋กœ ์—ด์–ด๋‘์–ด ๋‹ค๋ฅธ ์• ์ŠคํŽ™ํŠธ์—์„œ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

@Slf4j
@SpringBootTest
@Import(AspectV2.class)//๋ณ€๊ฒฝ
public class AopTest { ... }
  • AspectV2๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ๋‹ค.

์Šคํ”„๋ง AOP ๊ตฌํ˜„ - V3

์–ด๋“œ๋ฐ”์ด์Šค ์ถ”๊ฐ€

๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด์ž.

  • ํ•ต์‹ฌ ๋กœ์ง ์‹คํ–‰ ์ง์ „์— ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘

  • ํ•ต์‹ฌ ๋กœ์ง ์‹คํ–‰

    • ํ•ต์‹ฌ ๋กœ์ง ์‹คํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฉด ์ปค๋ฐ‹

    • ํ•ต์‹ฌ ๋กœ์ง ์‹คํ–‰์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑ

@Slf4j
@Aspect
public class AspectV3 {

    @Pointcut("execution(* hello.aop.order..*(..))")
    private void allOrder(){} //ํฌ์ธํŠธ์ปท ์‹œ๊ทธ๋‹ˆ์ฒ˜

    //ํด๋ž˜์Šค ์ด๋ฆ„ ํŒจํ„ด์ด *Service
    @Pointcut("execution(* *..*Service.*(..))")
    private void allService(){}

    @Around("allOrder()")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("[log] {}", joinPoint.getSignature());
        return joinPoint.proceed();
    }

    //hello.aop.order ํŒจํ‚ค์ง€์™€ ํ•˜์œ„ ํŒจํ‚ค์ง€ ์ด๋ฉด์„œ ๋™์‹œ์— ํด๋ž˜์Šค ์ด๋ฆ„ ํŒจํ„ด์ด *Service
    @Around("allOrder() && allService()")
    public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            log.info("[ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘] {}", joinPoint.getSignature());
            Object result = joinPoint.proceed();
            log.info("[ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹] {}", joinPoint.getSignature());
            return result;
        } catch (Exception e) {
            log.info("[ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ] {}", joinPoint.getSignature());
            throw e;
        } finally {
            log.info("[๋ฆฌ์†Œ์Šค ๋ฆด๋ฆฌ์ฆˆ] {}", joinPoint.getSignature());
        }
    }
}
  • allOrder() ํฌ์ธํŠธ์ปท์€ hello.aop.order ํŒจํ‚ค์ง€์™€ ๊ทธ ํ•˜์œ„ ํŒจํ‚ค์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค.

  • allService() ํฌ์ธํŠธ์ปท์€ ํƒ€์ž… ์ด๋ฆ„ ํŒจํ„ด์ด(*Service)๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค.(ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค์— ๋ชจ๋‘ ์ ์šฉ)

  • @Around("allOrder() && allService()")

    • ํฌ์ธํŠธ์ปท์„ ์กฐํ•ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. &&(AND), ||(OR), !(NOT) ๋ชจ๋‘ ๊ฐ€๋Šฅํ•˜๋‹ค.

    • ๊ฒฐ๊ณผ์ ์œผ๋กœ doTransaction()์–ด๋“œ๋ฐ”์ด์Šค๋Š” orderService์—๋งŒ ์ ์šฉ๋œ๋‹ค.

@Import(AspectV3.class) //๋ณ€๊ฒฝ
@SpringBootTest
public class AopTest { ... }
## success() ์‹คํ–‰ ๊ฒฐ๊ณผ ์ฝ˜์†”
[log] void hello.aop.order.OrderService.orderItem(String)
[ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘] void hello.aop.order.OrderService.orderItem(String)
[orderService] ์‹คํ–‰
[log] String hello.aop.order.OrderRepository.save(String)
[orderRepository] ์‹คํ–‰
[ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹] void hello.aop.order.OrderService.orderItem(String)
[๋ฆฌ์†Œ์Šค ๋ฆด๋ฆฌ์ฆˆ] void hello.aop.order.OrderService.orderItem(String)
img_2.png
  • ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ์ˆœ์„œ๊ฐ€ doLog() -> doTransaction() ์ˆœ์„œ๋กœ ์ž‘๋™ํ•œ๋‹ค.

  • ์–ด๋“œ๋ฐ”์ด์Šค๊ฐ€ ์ ์šฉ๋˜๋Š” ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

  • ์‹คํ–‰ ์‹œ๊ฐ„์„ ์ธก์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ ํŠธ๋žœ์žญ์…˜๊ณผ ๊ด€๋ จ๋œ ์‹œ๊ฐ„์„ ์ œ์™ธํ•˜๊ณ  ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํŠธ๋žœ์žญ์…˜ ์ดํ›„์— ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ์•ผ ํ•  ๊ฒƒ์ด๋‹ค.

Last updated