Aspect Oriented Programming의 자로 관점 지향 프로그래밍입니다.
횡단관심사를 분리하여 개발하는 것을 말합니다.
횡단의 사전적 정의는 동서의 방향으로 가로지르는 것 입니다.
프로그래밍에서는 여러 부분에서 공통적으로 사용되는 기능입니다.
예시로는 트랜잭션, 로깅, 인증, 인가 등이 있습니다.

메서드의 주요 기능입니다. 회원가입의 경우 중복되는 id,닉네임이 있는지 확인 후 repository에 저장하는 기능입니다.
핵심 기능이 아닌 부가적인 기능입니다. @Transactional등의 어노테이션이 있습니다.
여러 곳에서 공통적으로 발생하는 부가기능입니다.
AOP는 핵심기능과 횡단관심사(부가기능)을 분리해서 관리, 개발하는 것을 말합니다.
실제로 실행되는 횡단관심사(부가기능) 코드입니다.
프로젝트 진행시 어드비아스는 로깅처리, 인증인가, 트랜잭션같은 부가기능으로 활용될 수 있습니다.
어드바이스를 적용할 구체적인 범위를 선택하는 규칙입니다.
특정 패키지내의 메서드들이 대상이 될수도, 어노테이션으로 만들어 해당 컨트롤러에만 적용시킬수도 있습니다.
AOP에서 어드바이스가 적용되는 객체입니다. 특정 클래스가 타겟이되면, 그 클래스내의 모든 메서드들이 어드바이스의 적용을 받습니다.
어드바이스가 적용될 수 있는 실행 지점입니다. 메서드 기준으로 어드바이스가 동작하면, 메서드들이 조인포인트가 됩니다.
포인트컷, 어드바이를 하나로 묶은 모듈입니다.


이 두 클래스는 Admin사용자만 접근이 가능합니다.
이 포함된 AOP를 구현해야 합니다.
@Around("AdminLogsAnnotation()")
public Object adminAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
LocalDateTime startTime = LocalDateTime.now();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
String userId = String.valueOf(request.getAttribute("userId"));
log.info("userId ={} ", userId);
String url = String.valueOf(request.getAttribute("requestURL"));
log.info("url = {} ", url);
}
Object proceed = joinPoint.proceed();
log.info("startTime = {}", String.valueOf(startTime));
return proceed;
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
httpRequest.setAttribute("userId", Long.parseLong(claims.getSubject()));
httpRequest.setAttribute("email", claims.get("email"));
httpRequest.setAttribute("userRole", claims.get("userRole"));
httpRequest.setAttribute("requestURL", url);