Spring AOP

DOYOUNG KIMยท2023๋…„ 11์›” 29์ผ
0

Springํ”„๋ ˆ์ž„์›Œํฌ

๋ชฉ๋ก ๋ณด๊ธฐ
6/18

๐Ÿ’ป ์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ 
์‹ค์ œ ๊ฐ•์˜ ๋งํฌ

Spring AOP

AOP ๋Š” Aspect Oriented Programming์˜ ์•ฝ์ž๋กœ ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด ํ•ต์‹ฌ ๋กœ์ง, ๊ณตํ†ต ๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด์„œ ๋ชจ๋“ˆํ™” ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด์ž๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๊ณ„์† ๋งŒ๋“  ํšŒ์› ๊ฐ€์ž…, ์กฐํšŒ ๋กœ์ง์— ๋Œ€ํ•œ ํ˜ธ์ถœ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค
์ด๋Ÿด๋•Œ ํ•ต์‹ฌ ์‚ฌํ•ญ์€ ํšŒ์› ๊ฐ€์ž… ์„œ๋น„์Šค, ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์ด ํ˜ธ์ถœ ์‹œ๊ฐ„ ์ธก์ •์ด๋‹ค.

ํ•ต์‹ฌ ์‚ฌํ•ญ๊ณผ ๊ณตํ†ต ์‚ฌํ•ญ์ด ๋ถ„๋ฆฌ๋˜์ง€ ์•Š์€ ์ฑ„๋กœ ์‹œ๊ฐ„ ์ธก์ •ํ•˜๋Š” ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž

public Long join(Member member) {
 long start = System.currentTimeMillis();
   try {
     validateDuplicateMember(member); //์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ
     memberRepository.save(member);
     return member.getId();
   } finally {
     long finish = System.currentTimeMillis();
     long timeMs = finish - start;
     System.out.println("join " + timeMs + "ms");
   }
 }

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ try ๋ฅผ ํ†ตํ•ด์„œ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ์— ์‹œ์ž‘๊ณผ ๋์˜ ์‹œ๊ฐ„์„ ์ธก์ •ํ•ด์•ผํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์‹œ๊ฐ„ ์ธก์ •์€ ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ์ด ์•„๋‹˜
  • ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง์€ ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์ž„
  • ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๋กœ์ง๊ณผ ํ•ต์‹ฌ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์˜ ํ˜ผํ•ฉ์œผ๋กœ ์œ ์ง€ ๋ณด์ˆ˜ ์–ด๋ ค์›€
  • ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง์„ ๋ณ„๋„์˜ ๊ณต๋™ ๋กœ์ง์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์–ด๋ ค์›€
  • ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง ๋ณ€๊ฒฝ์‹œ ๋ชจ๋“  ๋กœ์ง์„ ์ฐพ์•„๊ฐ€๋ฉด ๋ณ€๊ฒฝ ํ•ด์•ผํ•จ

์˜ˆ๋ฅผ ๋“ค์–ด์„œ 100๊ฐœ์˜ ๋ฉ”์†Œ๋“œ์˜ ์‹œ๊ฐ„ ์ธก์ •์„ ์œ„ํ•ด์„œ 100๊ฐœ์˜ ๋ฉ”์†Œ๋“œ์— ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์•ผํ•˜๊ณ  ms ์„ s ๋กœ ๋ณ€๊ฒฝ์‹œ ๋‹ค์‹œ 100๊ฐœ๋ฅผ ๋ชจ๋‘ ๋ณ€๊ฒฝํ•ด์•ผํ•จ

AOP ์ ์šฉ

๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ๊ณผ ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ์„ ๋ถ„๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœํ•œ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ ์ฒ˜๋Ÿผ ๊ธฐ์กด ์„œ๋น„์Šค ๋กœ์ง์„ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ์ƒˆ๋กญ๊ฒŒ ๊ณตํ†ต ์‚ฌํ•ญ์„ ๊ฐœ๋ฐœํ•ด์„œ ์—ฐ๊ฒฐํ•˜๋Š”๊ฒŒ ์ค‘์š”'

์‹œ๊ฐ„ ์ธก์ •์„ ํ•˜๋Š” AOP ์†Œ์Šค ์ฝ”๋“œ์ด๋‹ค.
@Around("execution( hello.hellospring..(..))") ๋ฅผ ํ†ตํ•ด์„œ ์ด AOP ๊ฐ€ ์ ์šฉ๋œ ํด๋ž˜์Šค ๋ฒ”์œ„๋ฅผ ์ •ํ•œ๋‹ค.

๊ทธ ์ด์™ธ์˜ ๋กœ์ง์€ ๋™์ผํ•œ๋ฐ joinPoint.proceed()๋ฅผ ํ†ตํ•ด์„œ ์‹คํ–‰์„ ์‹œํ‚จ๋‹ค๊ณ  ํ•œ๋‹ค.

  • ์†Œ์Šค ์ฝ”๋“œ

package hello.hellospring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeTraceAop {

    @Around("execution(* hello.hellospring..*(..))")
    public Object excute(ProceedingJoinPoint joinPoint) throws Throwable{
        long start = System.currentTimeMillis();
        System.out.println("START : " + joinPoint.toString());
        try{
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("END : " + joinPoint.toString() + " " + timeMs + "ms");
        }

    }
}
  • ์‹คํ–‰ํ™”๋ฉด

์ด๋ ‡๊ฒŒ AOP๋ฅผ ํ†ตํ•ด์„œ ๋ถ„๋ฆฌ์‹œ ์–ป๋Š” ์ด์ ์€ ๋ฌด์—‡์ธ๊ฐ€??

  • ๊ด€์‹ฌ ์‚ฌํ•ญ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ
  • ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง์„ ๋ณ„๋„์˜ ๊ณตํ†ต ๋กœ์ง์œผ๋กœ ๋งŒ๋“ฌ
  • ํ•ต์‹ฌ ๊ด€๋ฆฌ ์‚ฌํ•ญ ๊ฐ€๋…์„ฑ, ๊ฐ„๊ฒฐ์„ฑ ์œ ์ง€
  • ๋ณ€๊ฒฝ ํ•„์š”ํ•˜๋ฉด ์‹œ๊ฐ„ ์ธก์ • ๋กœ์ง๋งŒ ๋ถ„๋ฆฌ
  • ์›ํ•˜๋Š” ์ ์šฉ ๋Œ€์ƒ ์„ค์ • ๊ฐ€๋Šฅ

AOP ๋™์ž‘ ๋ฐฉ์‹

๊ธฐ์กด์˜ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€๋ฐ ์—ฌ๊ธฐ์„œ ํ”„๋ก์‹œ๋กœ ๊ฐ€์งœ ๋ฉค๋ฒ„ ์„œ๋น„์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค,
๊ฐ€์งœ ๋ฉค๋ฒ„ ์„œ๋น„์Šค๊ฐ€ ์ปจํŠธ๋กค๋Ÿฌ์˜ ์š”์ฒญ์„ ๋จผ์ € ๋ฐ›๊ณ  ์ดํ›„ ์‹ค์ œ ๋ฉค๋ฒ„ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

AOP ์ ์šฉ๋œ ์ „์ฒด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ๋ชจ์Šต์ด๋‹ค.
์™œ ์ด๋ ‡๊ฒŒ ๋˜๋Š”์ง€ ์›๋ฆฌ, ์ถ”๊ฐ€ ์˜ˆ์ œ ๋“ฑ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ ๊ฐ•์˜์—์„œ ์ถ”๊ฐ€ ์„ค๋ช… ์˜ˆ์ •์ด๋‹ค.

profile
๋งค์ผ 1%์”ฉ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ ๊ณต๋ถ€ ๋ธ”๋กœ๊ทธ ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด