๋ฐ์ํ
์์กด์ฑ ์ถ๊ฐ
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
์ฌ์ฉ ๋ฐฉ์
- Aspect ์ ์ : @Aspect ์ ๋ํ ์ด์ ์ ์ฌ์ฉํด์ Aspect ํด๋์ค๋ฅผ ์ ์ํ๋ค
- Advice ์ ์ฉ : @Before, @After, @Around ๋ฑ ๋ค์ํ Advice๋ฅผ ๋ฉ์๋์ ์ ์ฉํ๋ค. ํน์ ์์ ์ ์ด๋ค ์คํ ๋ก์ง์ ์คํํ ์ง ์ ์ํ๋ค.
- Pointcut ์ค์ : execution ํํ์ ๋ฑ์ ํตํด ํน์ ๋ฉ์๋, ํจํค์ง ๋ฑ์๋ง Aspect๊ฐ ์ ์ฉ๋๋๋ก ์ค์ ํ๋ค
- AOP ํ์ฑํ : @EnableAspectJAuotProxy ์ ๋ํ ์ด์ ์ Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ํด๋์ค์ ์ถ๊ฐํด AOP๋ฅผ ํ์ฑํ ํ๋ค
@EnableAspectJAutoProxy
- ์คํ๋ง ์ปจํ ์คํธ ๋ด์์ AspectJ AOP ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ์ ๋ํ ์ด์
- AOP ํ๋ก์ ๋น์ ์๋์ผ๋ก ๋ฑ๋กํ๊ณ AOP๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋จ
- ํด๋น ์ ๋ํ ์ด์ ์ ์ฌ์ฉํ์ง ์์๋ AspectJ AOP ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ์ ์์
๋์๊ณผ์
- AOP๊ฐ ์ ์ฉ๋ ๋ฉ์๋ ํธ์ถ ์ Spring์ ์๋์ผ๋ก ์ค์ ๋ Advice๋ฅผ ์คํ
- ์๋ฅผ ๋ค์ด @Around Advice๊ฐ ์ค์ ๋ ๋ฉ์๋๋ AOP ํ๋ก์๊ฐ ํด๋น ๋ฉ์๋ ํธ์ถ์ ๊ฐ๋ก์ฑ ํ ๋ฉ์๋ ์คํ ์ ํ ์ง์ ๋ ๋ก์ง์ ์ํ
์๊ฐ ์ธก์ Aspect ์์
- com.youable.aop_example.service.BankService์ ๋ฉ์๋๊ฐ ์คํ๋ ๋ ๋ก๊น ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์์
package com.youable.aop_example.service;
@Service
@RequiredArgsConstructor
public class BankService {
private final AccountRepository accountRepository;
private final TransactionRepository transactionRepository;
public String registAccount(
RegistAccountRequest request
) {
String accountNumber = UniqueValueGenerator.getAccountNumber();
Account account = request.of(accountNumber, request);
accountRepository.save(account);
return accountNumber;
}
public Transaction deposit(TransactionRequest request) {
Account account = accountRepository.findByAccountNumber(request.getAccountNumber())
.orElseThrow(() -> new RuntimeException("account not found"));
// ์๋ต
return transaction;
}
public Transaction withdrawal(TransactionRequest request) {
Account account = accountRepository.findByAccountNumber(request.getAccountNumber())
.orElseThrow(() -> new RuntimeException("account not found"));
// ์๋ต
return transaction;
}
}
- registAccount, deposit, withdrawal ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์
@Aspect
@Component
@Slf4j
public class LoggingAspect {
@Around("execution(* com.youable.aop_example.service.BankService.*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
log.info("์คํ ๋ ๋ฉ์๋ ๋ช
: {}, ์คํ ์๊ฐ : {} ms",
joinPoint.getSignature().getName(), executionTime);
return result;
}
}
- ProceedingJoinPoint๋ก ๋ฉ์๋ ์ด๋ฆ์ ์ป์ ์ ์์
- BankService์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด AOP ์ค์ ์ ๋ฐ๋ผ @Around Advice๊ฐ ์คํ๋จ
- ProceedingJoinPoint์ proceed() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ค์ ๋ฉ์๋๊ฐ ์คํ๋จ
- proceed์ ์ํด ์ค์ ๋ฉ์๋๊ฐ ์๋ฃ๋๋ฉด ๋ฉ์๋ ํ์ ์์ ์ผ๋ก ๋์์ ์ดํ ๋ก์ง์ ์ํ
์คํ ๋ ๋ฉ์๋ ๋ช
: registAccount, ์คํ ์๊ฐ : 30 ms
- ์คํ ๊ฒฐ๊ณผ
๋ฉ์๋์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ธ์ค๊ธฐ
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class SecurityAspect {
private final AccountRepository accountRepository;
@Before("execution(* com.youable.aop_example.service.BankService.withdrawal(..))")
public void checkSecurity(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
TransactionRequest transaction = (TransactionRequest) args[0];
log.warn("Large amount withdrawal detected!");
Account account = accountRepository.findByAccountNumberAndOwnerNameAndPassword(transaction.getAccountNumber(), transaction.getOwnerName(), transaction.getPassword())
.orElseThrow(() -> new RuntimeException("fail authorization"));
}
}
- Advice์คํ์ ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ฅผ JoinPoint๋ก ๋ถํฐ ์ป์ ์ ์์
728x90
๋ฐ์ํ
'BE > ๐ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[gRPC]์ ๋ํด ์์๋ณด๊ธฐ (1) | 2024.11.24 |
---|---|
[Spring Boot] AOP๋ฅผ ํ์ฉํ ์ปค์คํ ์ ๋ ธํ ์ด์ ๋ง๋ค๊ธฐ (0) | 2024.11.19 |
[Spring Boot] AOP ๊ฐ๋ ์ ๋ฆฌ (0) | 2024.11.17 |
[MQTT] Spring Boot ์์ MQTT(mosquitto) ์ฌ์ฉํ๊ธฐ (4) | 2024.11.13 |
[Spring Boot] Custom Validation annotation (0) | 2024.11.10 |
๋๊ธ