728x90
반응형
AOP 란 관점 지향 프로그래밍 이라고 불린다.
서비스들의 비즈니스 메소드들은 복잡한 코드로 구성되어있다. 이럴때 비핵심적이지만 꼭 필요하면서, 공통화 할 수 있는 부분을 빼서
따로 관리하는것이다.
Request가 들어오고 Controller 까지의 동작방식은 다음과 같다
@Joinpoint
후보들 이라고 생각하면 된다.
나는 게시판 으로 예시를 들어보겠다. Controller에 있는 모든 메서드 들에게 후보군으로 설정하겠다.
방식은 2가지로 나눌 수 있다.
1. 어노테이션 방법 : 보통 이방식을 많이 사용한다.
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controllerPointcut() {
}
Controller * : Controller 밑에 있는 모든 메서드들을 말한다.
2. 위치 저장 문법:
@Pointcut("execution(* com.encore.board..controller..*.*(..))")
이렇게 2가지의 설정을 할 수 있다. 그러고 나서 내부 코드도 2가지의 방법으로 할 수 있는데 두 가지 모두 소개 할 예정이다.
일단 아래 코드 하기 전에 위에 2개중에 첫 번째 방법을 살려두고 두 번째 방법은 주석처리하였다.
1. @Before, @After 방법
@Before("controllerPointcut()")
public void beforService(JoinPoint joinPoint) {
log.info("Before Controller");
// 메소드가 실행되기 전에 인증, 입력값 검증등을 수행하는 용도로 사용하는 사전단계
// 사용자의 요청값을 출력하기 위해 HttpServletRequest 객체를 꺼내는 로직
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest req = servletRequestAttributes.getRequest();
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = new ObjectMapper().createObjectNode();
objectNode.put("Method Name ", joinPoint.getSignature().getName());
objectNode.put("CRUD Name", req.getMethod());
Map<String, String[]> paramMap = req.getParameterMap();
ObjectNode objectNodeDetail = new ObjectMapper().valueToTree(paramMap);
objectNode.set("user inputs", objectNodeDetail);
log.info("user request info " + objectNode);
}
@After("controllerPointcut()")
public void afterController(JoinPoint joinPoint) {
log.info("afterController");
}
메소드가 실행되기전에 Before가 실행된다.
만약에 홈페이지에서 로그인 을 클릭을 하면 로그인으로 넘어가기 전에 저 코드가 실행이 돼서
ObjectNode에 넣어둔 정보가 나오고 그런다음
After가 나온다.
2. @Around (주로 사용)
// 방식 2. @Around 사용 (가장 빈번하게 사용)
@Around("controllerPointcut()")
public Object controllerLogeer(ProceedingJoinPoint proceedingJoinPoint) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest req = servletRequestAttributes.getRequest();
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = new ObjectMapper().createObjectNode();
objectNode.put("Method Name ", proceedingJoinPoint.getSignature().getName());
objectNode.put("CRUD Name", req.getMethod());
Map<String, String[]> paramMap = req.getParameterMap();
ObjectNode objectNodeDetail = new ObjectMapper().valueToTree(paramMap);
objectNode.set("user inputs", objectNodeDetail);
log.info("user request info " + objectNode);
try {
// 본래의 컨트롤러 메서드 호출하는 부분
return proceedingJoinPoint.proceed();
} catch (Throwable e) {
log.error(e.getMessage());
throw new RuntimeException(e);
}finally {
log.info("end controller");
}
}
내부 로직은 똑같지만. After부분을 try로 부르면서 굳이 Before, After로 나눌 필요가 없어졌다.
주로 실무에서는 이 코드가 사용된다고 한다.
반응형
댓글