@Transactional
public class MemberService {
private final MemberRepository memberRepository;
//Dependency Injection
//현 클래스에서 생성하는 것이 아닌 외부에서 생성한 것을 넣어주는 형태
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
/**
* 회원 가입
*/
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");
}
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
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){
return memberRepository.findById(memberId);
}
}
join과 findMembers 메소드에 시간측정을 위한 코드를 추가하였다. 만약 이 서비스클래스에 메소드가 수십, 수백개 였다면 유지관리 및 보수가 어떨까?
-> 매우 힘듬
문제 사항
Cross-cutting-concern VS Core-concern
AOP를 위한 TimeTraceAop 클래스를 만들어준다
@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))") //hello.hellospring 하위 모든 파일에 적용하겠다는 의미
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");
}
}
}
helloController ----> memberService 의존하고있다
helloController에서 memberService의 메소드를 호출할때 memberService에서 호출
AOP가 있다면 스프링이 호출받는 memberService의 가짜 memberService(프록시 Proxy)를 만들어 낸다. 그럼 프록시(가짜)가 불리고 끝난 이후 joinPoint.preceed()
가 불리고 나서 실제 memberService를 호출한다