본문 바로가기

프로그래밍/- Spring

[ AOP ] AOP가 필요한 상황

 

 

AOP가 필요한 상황

 

 

➡️ AOP(Aspect Oriented Programming) : 관점 지향 프로그래밍 ( != OOP 객체 지향 프로그래밍)

  🔸로직을 핵심적, 부가적 관점으로 나누어 그를 기준으로 각각 모듈화

 

➡️ AOP 없이 모든 메소드의 호출 시간을 측정하고 싶다면?

  🔸시간 측정 로직을 모든 메서드에 추가해줘야 함

 

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import jakarta.transaction.Transactional;

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


@Transactional
//jpa 사용시 데이터 저장, 변경 시 트렌젝션 안에서 실행되기 때문에 트랜잭션 생성
public class MemberService {

    // 기계적인 역할의 리포지토리와 다르게 service는 더 비즈니스적으로 개발(메서드 이름 등)

    private final MemberRepository memberRepository;

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

    // 회원가입
    public Long join(Member member){

        long start = System.currentTimeMillis();

        try{
            // 중복 회원x
            validateDuplicateMember(member);
            memberRepository.save(member);
            return member.getId();

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

    private void validateDuplicateMember(Member member) {
        Optional<Member> result = memberRepository.findByName(member.getName());
        result.ifPresent(m -> { //만약 result가 있으면 (Optional의 메소드)
            throw new IllegalStateException("이미 존재하는 회원입니다.");  //중복회원이라는 예외 던져줌
        });
    }

    // 전체 회원 조회
    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 = " + timeMs + "ms");
        }
    }

    // 회원 한명 조회
    public Optional<Member> findOne(Long memberId){
        long start = System.currentTimeMillis();

        try{
            return memberRepository.findById(memberId);
        } finally{
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("findOne = " + timeMs + "ms");
        }
    }
}

 

  🔸 회원가입, 회원 조회와 같은 로직은 핵심적인 로직 >> 핵심 관심 사항

  🔸 시간 측정 로직은 핵심적인 로직이 아님 >> 공통 관심 사항

 

➡️ 핵심 관심 사항과 공통 관심 사항이 섞여 있으면 유지보수가 어려움

  🔸별도의 공통 로직으로 만들기 어려움

  🔸모든 로직을 찾아가며 변경햐애 하는 어려움