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" );
}
}
}
- ํ ์คํธ ์คํ ์ ์๋์ ๊ฐ์ด ์ฝ์์ฐฝ์ ์ถ๋ ฅ๋จ

* ํด๊ฒฐ
- ํ์๊ฐ์
, ํ์ ์กฐํ๋ฑ ํต์ฌ ๊ด์ฌ์ฌํญ๊ณผ ์๊ฐ์ ์ธก์ ํ๋ ๊ณตํต ๊ด์ฌ ์ฌํญ์ ๋ถ๋ฆฌํ๋ค.
- ์๊ฐ์ ์ธก์ ํ๋ ๋ก์ง์ ๋ณ๋์ ๊ณตํต ๋ก์ง์ผ๋ก ๋ง๋ค์๋ค.
- ํต์ฌ ๊ด์ฌ ์ฌํญ์ ๊น๋ํ๊ฒ ์ ์งํ ์ ์๋ค.
- ๋ณ๊ฒฝ์ด ํ์ํ๋ฉด ์ด ๋ก์ง๋ง ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
- ์ํ๋ ์ ์ฉ ๋์์ ์ ํํ ์ ์๋ค.
'๋ฐฑ์๋(Back-End) ๊ฐ๋ฐ > SpringBoot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SpringBoot] STS3 / jdk-11 ์ค์นํ๊ธฐ (0) | 2025.03.05 |
---|---|
[SpringBoot] 6.6_์คํ๋ง ๋ฐ์ดํฐ JPA (0) | 2025.02.26 |
[SpringBoot] 6.5_JPA (0) | 2025.02.26 |
[SpringBoot] 6.4_์คํ๋ง JdbcTemplate (0) | 2025.02.26 |
[SpringBoot] 6.3_์คํ๋ง ํตํฉ ํ ์คํธ (DB์ฐ๊ฒฐ) (0) | 2025.02.26 |