[Spring Boot] AOP

2021. 8. 20. 08:00ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”? ์ฃผ๋‹ˆํ•˜๋ž‘ ์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ AOP์— ๋Œ€ํ•ด ๊ณต๋ถ€ ํ•ด ๋ณด๋„๋ก ํ•  ๊ฒƒ์ด์—์š”.

๋ฐ”๋กœ ์‹œ์ž‘ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

 

์ฝ”๋“œ์— ๊ด€๋ จํ•œ ๋‚ด์šฉ์€ ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Github์—์„œ ํ™•์ธ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

 


 

๐Ÿ“‹ ๋ชฉ์ฐจ


01.[Spring Boot] thymeleaf์™€ Spring Boot
02.[Spring Boot] Spring Web ๊ฐœ๋ฐœ ๊ธฐ์ดˆ
03.[Spring Boot] ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - Backend
04.[Spring Boot] Service ๊ฐœ๋ฐœ ๋ฐ Test Case ์ž‘์„ฑ
05.[Spring Boot] Spring Bean๊ณผ ์˜์กด๊ด€๊ณ„
06.[Spring Boot] Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋ก
07.[Spring Boot] ๋“ฑ๋ก, ๋ชฉ๋ก ๋ณด๊ธฐ ๊ตฌํ˜„ํ•˜๊ธฐ
08.[Spring Boot] ๊ธฐ์กด ์ฝ”๋“œ ์† ์•ˆ๋Œ€๊ณ , ์„ค์ •์œผ๋กœ ๊ตฌํ˜„ Class ๋ณ€๊ฒฝ
09.[Spring Boot] ํ†ตํ•ฉ Test
10.[Spring Boot] JPA
11.[Spring Boot] Spring Data JPA
12.[Spring Boot] AOP

 


 

 

๐Ÿ“Œ AOP; Aspect Oriented Programming(๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)


AOP๋Š” ์–ด๋–ค Logic์„ ๊ธฐ์ค€์œผ๋กœ ํ•ต์‹ฌ์ ์ธ ๊ธฐ๋Šฅ๊ณผ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ๋‚˜๋ˆ„์–ด์„œ ๊ทธ ๊ด€์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ๋ชจ๋“ˆํ™” ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

๋ชจ๋“ˆํ™”๋ผ๋Š” ๊ฒƒ์€ ์–ด๋–ค ๊ณตํ†ต๋œ Logic์ด๋‚˜, ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ต๋‹ˆ๋‹ค!

 

๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ๊ตฌํ˜„ํ•œ Service, Repository ๋“ฑ์— ๊ฐ Method ๋™์ž‘ ์‹œ๊ฐ„์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”?

๊ฐ๊ฐ Method์— ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Coding์„ ํ•ด์„œ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๊ฒ ์ง€๋งŒ, ์ด๊ฒƒ์„ AOP๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ•œ ๋ฒˆ๋งŒ ์ž‘์„ฑํ•˜๋ฉด ๋๋‚˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์—์š”.

 

๋จผ์ € ๊ฐ๊ฐ Method์— ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Code๋ฅผ ๋ด๋ณผ๊ฒŒ์š”!

 

 

MemberService.java

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

// ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋ฐฉ์‹์˜ Service
//@Service
@Transactional
public class MemberService {   // Service ์ชฝ์€ ๋น„์ฆˆ๋‹ˆ์Šค ์šฉ์–ด์— ๋งž๊ฒŒ ์ด๋ฆ„ ๋“ฑ์„ ์ ์–ด์•ผ ํ•œ๋‹ค.
        // ์•„๋ž˜ ๋‚ด์šฉ์—์„œ repository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , Service Test์—์„œ ๋˜ new๋ฅผ ํ†ตํ•ด Repository๋ฅผ ์ƒ์„ฑํ•ด์„œ ํ…Œ์ŠคํŠธํ•˜๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋œ๋‹ค.
//  private final MemoryMemberRepository memberRepository = new MemoryMemberRepository();

    // ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€๋‹ค.
    private final MemberRepository memberRepository;

    // @Service๊ฐ€ ์žˆ๋Š” Service๊ฐ€ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ, @Autowired๊ฐ€ ๋ถ™์€ ์ƒ์„ฑ์ž๋Š” ์Šคํ”„๋ง์ด ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋นˆ์œผ๋กœ ๊ด€๋ฆฌํ•  ๋•Œ, ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ์ด ๋•Œ MemberService๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
//    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    } // ์ƒ์„ฑ์ž ๋

    // ํšŒ์› ๊ฐ€์ž…
    public Long join(Member member) {

        long start = System.currentTimeMillis();    // Method ํ˜ธ์ถœ์˜ ์‹œ์ž‘ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ ์–ธ

       // ๊ฐ™์€ ์ด๋ฆ„์ด ์žˆ๋Š” ์ค‘๋ณต ํšŒ์› ๊ฐ€์ž… ๋ฐฉ์ง€
//        Optional<Member> result = memberRepository.findByName(member.getName());
//
//        result.ifPresent(memeber -> { // ifPresent๋Š” ํ•ด๋‹น ๊ฐ’์ด Null์ด ์•„๋‹ˆ๊ณ , ์–ด๋–ค ๊ฐ’์ด ์žˆ์œผ๋ฉด ๋™์ž‘ (Option๋กœ ๊ฐ์‹ธ๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
//            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.");
//        });

        // ์œ„์— ์ฝ”๋“œ ๋ณด๋‹ค ๋” ์ข‹์€ ์ฝ”๋“œ
//        memberRepository.findByName(member.getName()).ifPresent(member1 -> {
//            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.")
//        });

        // ์œ„์˜ ์ฝ”๋“œ๋ฅผ Method ํ™” ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
        // ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์„ ํƒํ•˜๊ณ , Command + Option + M์„ ๋ˆŒ๋Ÿฌ์ค€๋‹ค.
        try {
            validateDuplicationMember(member);      // ์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ

            memberRepository.save(member);
            return member.getId();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("join Method ๋™์ž‘ ์‹œ๊ฐ„์€ " + timeMs + "ms ์ž…๋‹ˆ๋‹ค.");
        }
    } // join() ๋

    private void validateDuplicationMember(Member member) {
        // ์œ„์— ์ฝ”๋“œ ๋ณด๋‹ค ๋” ์ข‹์€ ์ฝ”๋“œ
        memberRepository.findByName(member.getName()).ifPresent(member1 -> {
            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.");
        });
    } // validateDuplicationMember() ๋

    public List<Member> findMembers() {
        long start = System.currentTimeMillis();

        try {
            return memberRepository.findAll();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("findMembers Method ๋™์ž‘ ์‹œ๊ฐ„์€ " + timeMs + "ms ์ž…๋‹ˆ๋‹ค.");
        } // try ๋ฌธ ๋

    } // findMembers() ๋

    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    } // findOne() ๋

} // Class ๋

 

์ฃผ๋‹ˆํ•˜๋ž‘์€ join(), findMembers()์— ๋™์ž‘ ์‹œ์ž‘ ์‹œ๊ฐ„๊ณผ ๋๋‚˜๋Š” ์‹œ๊ฐ„์— ๋Œ€ํ•œ Coding์„ ํ•œ ๊ฒƒ์ด์—์š”.

System.currentTimeMillis()๋Š” ๊ทธ Method๊ฐ€ ํ˜ธ์ถœ๋œ ์‹œ๊ฐ„์„ ์ฐ๋Š” Method์ด๋ฉฐ, ๋‹จ์œ„๋Š” ms์ธ ๊ฒƒ์ด์—์š”!

 

์œ„์—์„œ ๋ณด๋“ฏ์ด ๊ฐ Method์— ์ด๋Ÿฐ Logic์„ ์ถ”๊ฐ€ํ•œ๋‹ค๋ฉด ๋ช‡ ๊ฐœ ์•ˆ๋˜๋Š” Method๋ผ๋ฉด ํ•ด ๋ณผ๋งŒ ํ•˜์ง€๋งŒ, ๊ทธ๊ฒŒ ๋ช‡ ๋งŒ๊ฐœ์ •๋„ ๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์•„๋งˆ ํ”ผ๋ฅผ ํ† ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.

 

๊ฐ Method์— ์‹œ๊ฐ„ ์ธก์ • Logic์„ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ์˜ ๊ตฌ์„ฑ๋„

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฌธ์ œ์ ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํšŒ์›๊ฐ€์ž…, ํšŒ์› ์กฐํšŒ์— ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ์ด ์•„๋‹˜
  • ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Logic์€ ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ
  • ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Logic๊ณผ ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค Logic์ด ์„ž์—ฌ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.
  • ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Logic์„ ๋ณ„๋„์˜ ๊ณตํ†ต Logic์œผ๋กœ ๋งŒ๋“ค๊ธฐ ๋งค์šฐ ์–ด๋ ต๋‹ค.
  • ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” Logic ๋ณ€๊ฒฝ ์‹œ ๋ชจ๋“  Logic์„ ์ฐพ์•„๊ฐ€๋ฉด์„œ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

 

์ด๋ฅผ ์œ„ํ•ด AOP๋ผ๋Š” ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ํ•ด๊ฒฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

๊ฒฐ๊ตญ AOP๋Š” ๊ณตํ†ต ๊ด€์‹ฌ์‚ฌํ•ญ (Cross-cutting Concern)๊ณผ ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ (Core Concern)์„ ๋ถ„๋ฆฌ ์‹œํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

728x90

TimeTraceAop.java

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  // ์ด๋ ‡๊ฒŒ ํ•ด์„œ Bean์— ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ , SpringConfig์— @Bean์„ ์‚ฌ์šฉํ•˜์—ฌ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
public class TimeTraceAop { // MemberService Method ๋™์ž‘ ์‹œ๊ฐ„์„ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•œ AOP

    @Around("execution(* hello.hellospring..*(..))")    // hello.hellospring ๋ฐ‘์— ๋ชจ๋“  ๋‚ด์šฉ์— ์•„๋ž˜ Method ๋ชจ๋‘ ์ ์šฉ
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        System.out.println("START : " + joinPoint.toString() + " ์˜ Method ๋™์ž‘ ์‹œ๊ฐ„ Test๊ฐ€ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค!");
        try {
//            Object proceed = joinPoint.proceed();// ๋‹ค์Œ Method๋กœ ์ง„ํ–‰
//            return proceed;

            // ์œ„์˜ Code Inline์œผ๋กœ ํ•ฉ์นœ ๋ชจ์Šต
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;

            System.out.println("END : " +joinPoint.toString() + " ์˜ Method ๋™์ž‘ ์‹œ๊ฐ„์€ " + timeMs + "ms ์ž…๋‹ˆ๋‹ค!");
        } // try ๋ฌธ ๋
    } // excute() ๋
} // Class ๋

 

์œ„์™€ ๊ฐ™์ด AOP๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ค ๋ถ€๋ถ„์ด ์ข‹์•„์งˆ๊นŒ์š”?

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

 

 

@Aspect : ๋ถ€๊ฐ€์  ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋‚ด์šฉ๋“ค์„ ๋ชจ๋“ˆํ™” ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Annotion ๊ณตํ†ต์œผ๋กœ ์ ์šฉํ•  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ
                      ์ฆ‰, ํ•ด๋‹น Class๊ฐ€ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ Class์ž„์„ ์•Œ๋ ค์ฃผ๋Š” Annotion

@Component : AOP๋ฅผ Spring Bean์— ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ (@Aspect๋ฅผ ๋ช…์‹œ ํ–ˆ๋‹ค๊ณ  ํ•˜์—ฌ ์ž๋™์œผ๋กœ
                               Spring Bean์— ๋“ฑ๋ก๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ Bean ๋“ฑ๋ก์„ ์œ„ํ•ด ์‚ฌ์šฉ)

                               SpringConfig์— @Bean์„ ์‚ฌ์šฉํ•˜์—ฌ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์กด์žฌ

    @Bean
    public TimeTraceAop timeTraceAop() {    // aop/TimeTraceAop๋ฅผ Bean์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method
      return new TimeTraceAop();
    } // timeTraceAop() ๋

@Around : ๋Œ€์ƒ Entity Method ์‹คํ–‰ ์ „, ํ›„ ๋˜๋Š” ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ์ ์— ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์‹คํ–‰
                   ์ด๊ฒƒ์€ Advice์˜ ํ•œ ์ข…๋ฅ˜๋กœ ํ•ต์‹ฌ ๊ด€์‹ฌ์‚ฌ์˜ ์‹คํŒจ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ์‹คํ–‰๋˜๋„๋ก ํ•˜๋Š” Advice

        - execution(์ ‘๊ทผ ์ œ์–ด์ž, ๋ฐ˜ํ™˜ํ˜• Package๋ฅผ ํฌํ•จํ•œ Class Path Method Parameter)

@Around("execution(* hello.hellospring..*(..))")    // hello.hellospring ๋ฐ‘์— ๋ชจ๋“  ๋‚ด์šฉ์— ์•„๋ž˜ Method ๋ชจ๋‘ ์ ์šฉ

           ์ฒซ๋ฒˆ์งธ์— ๋ช…์‹œ๋œ *์€ ์ ‘๊ทผ์ œ์–ด์ž์™€ ๋ฐ˜ํ™˜ํ˜• ๋ชจ๋‘๋ฅผ ์ƒ๊ด€ํ•˜์ง€ ์•Š๊ณ , ์ ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ. 
           hello๋Š” Project Directory ์ค‘ java ๋ฐ‘์— ์žˆ๋Š” Package์ด๊ณ , ๊ทธ ๋‹ค์Œ์€ hellospring์ด๋‹ค.
           ์ฆ‰, hello ๋ฐ‘์— ์žˆ๋Š” ๋ชจ๋“  ๋‚ด์šฉ์— ์•„๋ž˜ ๋ช…์‹œ๋œ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๊ณ ,
           (..) ์ด๊ฒƒ์˜ ์˜๋ฏธ๋Š” Method Parameter๊ฐ€ ๋ช‡ ๊ฐœ๊ฐ€ ์กด์žฌํ•˜๋˜์ง€ ์ƒ๊ด€ ์—†์ด ์‹คํ–‰ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ

 

 

    ๐Ÿ“ Spring AOP ๋™์ž‘ ๋ฐฉ์‹

         ๐Ÿ‘‰ AOP ์ ์šฉ ์ „ Class ๊ฐ„ ์˜์กด ๊ด€๊ณ„

 

AOP ์ ์šฉ ์ „์—๋Š” MemberController๊ฐ€ MemberService๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ์–ด Controller๊ฐ€ Service๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ด€๊ณ„ ์˜€์Šต๋‹ˆ๋‹ค!

 

 

         ๐Ÿ‘‰ AOP ์ ์šฉ ํ›„ Class ๊ฐ„ ์˜์กด ๊ด€๊ณ„

 

Spring์€ AOP๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ฒŒ ๋˜๋ฉด ๊ฐ€์งœ Service๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์—์š”. ์ด๊ฒƒ์„ Proxy๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ต๋‹ˆ๋‹ค!

์ฆ‰, Spring์ด ์˜ฌ๋ผ์˜ค๋ฉด์„œ Container์— Bean์„ ๋“ฑ๋กํ•  ๋•Œ, ์ง„์งœ Spring Bean์ด ์•„๋‹Œ Proxy Spring Bean์„ ์•ž์— ์„ธ์›Œ๋‘๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ๊ฐ€์งœ Proxy์— ์ž‘์—…์ด ๋๋‚˜๋ฉด joinPoint.proceed()๋ฅผ ํƒ€๋ฉด์„œ ์ด๊ฒƒ์ €๊ฒƒ ์ž‘์—…์„ ํ•œ ๋’ค ์ง„์งœ Spring Bean์„ ํ˜ธ์ถœํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋œ๋‹ต๋‹ˆ๋‹ค!

๊ทธ๋ž˜์„œ Controller๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ Proxy ๊ธฐ์ˆ ๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ€์งœ Service๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด์—์š”.

 

         ๐Ÿ‘‰ AOP ์ ์šฉ ์ „ ์ „์ฒด ๊ตฌ์„ฑ

 

 

         ๐Ÿ‘‰ AOP ์ ์šฉ ํ›„ ์ „์ฒด ๊ตฌ์„ฑ

 

 

         ๐Ÿ‘‰ ์‹ค์ œ Proxy ์ฃผ์ž… ์—ฌ๋ถ€ Console ํ†ตํ•ด ํ™•์ธ

 

ํ‘œ์‹œ๋œ ๊ณณ์„ ๋ณด๋ฉด MemberService๋กœ ๋๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ EnhancerBy ๋ญ๋ผ๊ณ  ๋ง‰ ์ ํ˜€์„œ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด์—์š”.

CGLIB๋ผ๊ณ , CGLibrary๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น Service๋ฅผ ๋ณต์ œํ•˜์—ฌ ์กฐ์ž‘ํ•˜๋Š” ๊ธฐ์ˆ ์ธ ๊ฒƒ์ด์—์š”.

์ด๋Ÿฐ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ Proxy ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ต๋‹ˆ๋‹ค!

 

 

 


 

์ฃผ๋‹ˆํ•˜๋ž‘์˜ ๊ธ€์ด ๋งˆ์Œ์— ๋“œ์…จ๋‚˜์š”? ๊ตฌ๋…๊ณผ ๊ณต๊ฐ! ๊ทธ๋ฆฌ๊ณ , ๋Œ“๊ธ€์€ ์ฃผ๋‹ˆํ•˜๋ž‘์—๊ฒŒ ๋งŽ์€ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค

728x90
๋ฐ˜์‘ํ˜•

'Back-End ์ž‘์—…์‹ค > Spring Framework' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[๋„์ „ ๊ธฐ์ˆ !] ํ…Œ์ŠคํŠธ ์ฝ”๋“œ  (0) 2021.08.24
[๋„์ „ ๊ธฐ์ˆ !] Web Layer  (0) 2021.08.23
[Spring Boot] Spring Data JPA  (0) 2021.08.19
[Spring Boot] JPA  (0) 2021.08.18
[Spring Boot] ํ†ตํ•ฉ Test  (0) 2021.08.17