AOP(Aspect Oriented Programming)
관점 지향 프로그래밍으로 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화 하는 것이다.
@Slf4j
@Aspect
@Component
public class AroundAop {
// 포인트컷 : 언제 동작하는가?
@Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
public void setPointCut() { }
// 어드바이스 : 무슨 동작을 하는가?
@Around("setPointCut()")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
/*
* Around 어드바이스
* 1. 반환타입 : Object
* 2. 메소드명 : 마음대로
* 3. 매개변수 : ProceedingJoinPoint
*/
log.info("=================================================================="); // 포인트컷 실행 이전에 실행(@Before 이전에 동작)
Object obj = proceedingJoinPoint.proceed(); // 포인트컷이 실행되는 시점
log.info("{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())); // 포인트컷 실행 이후에 실행(@After 이전에 동작)
return obj;
}
}
@Slf4j // private static final Logger log = LoggerFactory.getLogger(BeforeAop.class);
@Aspect
@Component
public class BeforeAop {
// 포인트컷 : 언제 동작하는가?
@Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
public void setPointCut() { } // 이름만 제공하는 메소드(이름은 마음대로 본문도 필요 없다.)
// 어드바이스 : 무슨 동작을 하는가?
@Before("setPointCut()")
public void beforeAdvice(JoinPoint joinPoint) {
/*
* Before 어드바이스
* 1. 반환타입 : void
* 2. 메소드명 : 마음대로
* 3. 매개변수 : JoinPoint
*/
/* ContactController의 모든 메소드가 동작하기 전에 요청(방식/주소/파라미터) 출력하기 */
// 1. HttpServletRequest
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
// 2. 요청 파라미터 -> Map 변환
Map<String, String[]> map = request.getParameterMap();
// 3. 요청 파라미터 출력 형태 만들기
String params = "";
if(map.isEmpty()) {
params += "No Parameter";
} else {
for(Map.Entry<String, String[]> entry : map.entrySet()) {
params += entry.getKey() + ":" + Arrays.toString(entry.getValue()) + " ";
}
}
// 4. 로그 찍기 (치환 문자 {} 활용)
log.info("{} {}", request.getMethod(), request.getRequestURI()); // 요청 방식, 요청 주소
log.info("{}", params); // 요청 파라미터
}
}
@Slf4j
@Aspect
@Component
public class AfterAop {
// 포인트컷 : 언제 동작하는가?
@Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
public void setPointCut() { }
// 어드바이스 : 무슨 동작을 하는가?
@After("setPointCut()")
public void afterAdvice(JoinPoint joinPoint) {
/*
* After 어드바이스
* 1. 반환타입 : void
* 2. 메소드명 : 마음대로
* 3. 매개변수 : JoinPoint
*/
// 로그 찍기
log.info("==================================================================");
}
}
@After @Before @ Around 를 붙인 곳에서는
After Before Around
와 같이 쪽에 화살표가 붙는다.