๋ฐฑ์—”๋“œ(Back-End) ๊ฐœ๋ฐœ/SpringBoot

[SpringBoot] 7_AOP(๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)

rabo93 2025. 2. 27. 02:14
AOP๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ

- ๋ชจ๋“  ๋ฉ”์†Œ๋“œ์˜ ํ˜ธ์ถœ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? 

- '๊ณตํ†ต' ๊ด€์‹ฌ ์‚ฌํ•ญ vs 'ํ•ต์‹ฌ' ๊ด€์‹ฌ ์‚ฌํ•ญ

- ํšŒ์› ๊ฐ€์ž… ์‹œ๊ฐ„, ํšŒ์› ์กฐํšŒ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?

package hello.hello_spring.service;

import hello.hello_spring.domain.Member;
import hello.hello_spring.repository.MemberRepository;
import hello.hello_spring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Transactional
public class MemberService {
    // private final MemberRepository memberRepository = new MemoryMemberRepository();
    // DI (์˜์กด์„ฑ ์ฃผ์ž…) ํŒจํ„ด์œผ๋กœ ๋ฐ”๊พธ๊ธฐ
    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    /*
    * ํšŒ์›๊ฐ€์ž…
    * */
    public long join(Member member) {
        // AOP
        // ** ๊ณตํ†ต ๊ด€์‹ฌ ๋กœ์ง (๊ฐ ๋ฉ”์„œ๋“œ๋งˆ๋‹ค ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ์ฝ”๋“œ ์ถ”๊ฐ€.. ์–ธ์ œ ๋‹คํ•˜๋ƒ)
        long start = System.currentTimeMillis();

        try {
            //--------------------------------------
            // ** ํ•ต์‹ฌ ๊ด€์‹ฌ ๋กœ์ง
            //๊ฐ™์€ ์ด๋ฆ„์ด ์žˆ๋Š” ์ค‘๋ณต ํšŒ์› X
            validateDuplicateMember(member); // ์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ
            memberRepository.save(member);
            return member.getId(); //longํƒ€์ž…์˜ id๊ฐ€ ๋ฆฌํ„ด๋จ
            //--------------------------------------

        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("join " + timeMs + "ms");
        }

        
    }
	
    //๋ฐ‘์— ๋ฉ”์„œ๋“œ๋“ค๋„ ํ•ด์•ผํ•˜์ง€๋งŒ ์ƒ๋žตํ•˜๊ฒ ์Œ!!
    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
                        .ifPresent(m -> {
                            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
                        });
    }


    /*
    * ์ „์ฒด ํšŒ์› ์กฐํšŒ
    * */
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

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


}

 

* ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ์ !!

- ํšŒ์›๊ฐ€์ž…, ํšŒ์› ์กฐํšŒ์— ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ์ด ์•„๋‹ˆ๋‹ค.

- ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๋กœ์ง์€ ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์ด๋‹ค.

- ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๋กœ์ง๊ณผ ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค์˜ ๋กœ์ง์ด ์„ž์—ฌ์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.

- ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๋Š” ๋กœ์ง์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋ชจ๋“  ๋กœ์ง์„ ์ฐพ์•„๊ฐ€๋ฉด์„œ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

 

 


AOP ์ ์šฉ (AOP: Aspect Oriented Programming)

: ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ vs ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ ๋ถ„๋ฆฌ!!

 

  • ๊ณตํ†ต ๊ด€์‹ฌ ๋กœ์ง์„ TimeTraceAop.java ํด๋ž˜์Šค์— ๋”ฐ๋กœ ์ž‘์„ฑํ•˜์—ฌ ๋ถ„๋ฆฌ (MemberService.java ํด๋ž˜์Šค์—๋Š” ํ•ต์‹ฌ ๊ด€์‹ฌ ๋กœ์ง๋งŒ ์ž‘์„ฑ)
package hello.hello_spring.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.hello_spring..*(..))") //AOP ์„ค์ •ํ•  ๊ฒฝ๋กœ
    public Object execute(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" );
        }

    }

}

 

 

  • ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ˜์†”์ฐฝ์— ์ถœ๋ ฅ๋จ

 

* ํ•ด๊ฒฐ

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