AOP는 간단하게 객체의 부가기능 설계라고 보면된다.(OOP 주기능)
주기능 사이에 부가기능을 넣어줄수 있다.
AOP는 부가기능으로 어드바이스로
@Around 로 핵심기능 수행전과후에 동작하게 할수 있다.
어드바이스의 종류는 하기와 같이 5가지가 있다.
포인트 컷의 expression language의 형태는 하기와 같다.
참고로 Setter, Getter , NoArgsConstructor, Entity
는 어노테이션으로 스프링부트에서 자동생성가능하다 할때
ApiUseTime 을 JPA로 DB와 연결하고
API 사용시간의 시작과 끝시간을
사용자마다 계속 등록하고 업데이트해주는 기능을 만들수 있다.
즉 사용자의 API사용시간~!
최다 사용시간을 사용하는 부가기능을 만드는데 있어서
@Aspect
@Component
public class UseTimeAop {
private final ApiUseTimeRepository apiUseTimeRepository;
public UseTimeAop(ApiUseTimeRepository apiUseTimeRepository) {
this.apiUseTimeRepository = apiUseTimeRepository;
}
@Around("execution(public * com.lms.springcore.controller..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
// 측정 시작 시간
long startTime = System.currentTimeMillis();
try {
// 핵심기능 수행
Object output = joinPoint.proceed();
return output;
} finally {
// 측정 종료 시간
long endTime = System.currentTimeMillis();
// 수행시간 = 종료 시간 - 시작 시간
long runTime = endTime - startTime;
// 로그인 회원이 없는 경우, 수행시간 기록하지 않음
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getPrincipal().getClass() == UserDetailsImpl.class) {
// 로그인 회원 정보
UserDetailsImpl userDetails = (UserDetailsImpl) auth.getPrincipal();
Users loginUser = userDetails.getUser();
// API 사용시간 및 DB 에 기록
ApiUseTime apiUseTime = apiUseTimeRepository.findByUser(loginUser)
.orElse(null);
if (apiUseTime == null) {
// 로그인 회원의 기록이 없으면
apiUseTime = new ApiUseTime(loginUser, runTime);
} else {
// 로그인 회원의 기록이 이미 있으면
apiUseTime.addUseTime(runTime);
}
System.out.println("[API Use Time] Username: " + loginUser.getUsername() + ", Total Time: " + apiUseTime.getTotalTime() + " ms");
apiUseTimeRepository.save(apiUseTime);
}
}
}
}
기존의 CRUD API 의 주기능에
API 사용시간츨 측정하는 부가기능을
AOP로 만드는 것이다.
AOP로 만들면 코드중복이 사라지고
주기능에 영향을 최소로 주면서
만들수 있어서 안정적이고 유지보수에도 편리하다.
이런것을 예외처리에도 적용할 수 있다.
@Getter
@Setter
public class RestApiException {
private String errorMessage;
private HttpStatus httpStatus;
}
@RestControllerAdvice
public class RestApiExceptionHandler {
@ExceptionHandler(value = { IllegalArgumentException.class })
public ResponseEntity<Object> handleApiRequestException(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException();
restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
restApiException.setErrorMessage(ex.getMessage());
return new ResponseEntity(
restApiException,
HttpStatus.BAD_REQUEST
);
}
}
@RestControllerAdvice = @ControllerAdvice + @ResponseBody
[참고 @Transactional - Propagation.REQUIRED_NEW ]
LIST
'4차산업혁명의 일꾼 > Java&Spring웹개발과 서버 컴퓨터' 카테고리의 다른 글
리팩토링(refactoring) (0) | 2022.07.18 |
---|---|
Rest API 와 @ResponseBody (0) | 2022.07.18 |
스프링 DI~ 의존성 주입이라 불리는 객체의 상황적 연결 (0) | 2022.07.03 |
쇼미더코드 : 원티드 주관 코딩테스트 대회 후기 (0) | 2022.07.02 |
현대모비스 2022 SW 알고리즘 경진대회 개최 후기 (0) | 2022.07.01 |