AOP(Aspect Oriented Programming)
AOP는 관점 지향 프로그래밍이라고 해석할 수 있습니다. 비즈니스 로직의 기준을 정하고 그 기준에 따라 나눈 부분을 관점이라고 한다면, 이 관점을 모듈화 하는 것입니다.
AOP의 용어
Aspect : 여러 클래스에서 중복적으로 사용되는 공통된 관점을 모듈화 한 것
Joinpoint : method 또는 excepition와 같은 끼어들 수 있는 지점
Pointcut : 특정 Joinpoint에서 Aspect가 적용할 Advice를 일치시키기 위한 것
Advice: 특정 Joinpint에서 Aspect가 한 액션입니다.
Target : Aspect를 적용하는 지점
Logging 구현
실제 서비스에서 로그를 남기는 것은 선택이 아닌 필수입니다. 로그를 남겨서 에러가 발생하였을 때, 즉각적으로 대처할 때 주요할 것이며, 실제 내가 작성한 코드의 흐름이 정상적으로 동작하고 있는지에 대한 판단 여부에도 많은 도움이 될 수 있습니다. 물론 이외에도 여러 가지 이유가 있을 수 있습니다!
1. 의존성 추가
Spring boot에서 AOP를 사용하기 위해서는 의존성을 추가해줘야 합니다. maven을 빌드 툴로 프로젝트를 생성했기 때문에 pom.xml에 아래와 같이 추가해줍니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. EnableAspectJAutoProxy 추가
@EnableAspectJAutoProxy // AOP 사용
@SpringBootApplication
public class BeApplication {
public static void main(String[] args) {
SpringApplication.run(BeApplication.class, args);
}
}
3. LogAspect.class 생성
Aspect 어노테이션을 추가하여 이 클래스가 공통된 관점을 모듈화한 Aspect라는 것을 명시합니다. 그리고 Component 어노테이션을 추가하여 Bean으로 등록해줍니다.
@Around를 사용하여 method를 target으로 지정하여 com.ecommerce.be 패키지 아래 객체의 모든 method에 Aspect를 적용합니다.
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Around("within(com.ecommerce.be..*)")
public Object logging(ProceedingJoinPoint pjp) throws Throwable {
String params = getRequestParams();
long startAt = System.currentTimeMillis();
logger.info("----------> REQUEST : {}({}) = {}", pjp.getSignature().getDeclaringTypeName(),
pjp.getSignature().getName(), params);
Object result = pjp.proceed();
long endAt = System.currentTimeMillis();
logger.info("----------> RESPONSE : {}({}) = {} ({}ms)", pjp.getSignature().getDeclaringTypeName(),
pjp.getSignature().getName(), result, endAt-startAt);
return result;
}
// get requset value
private String getRequestParams() {
String params = "";
RequestAttributes requestAttribute = RequestContextHolder.getRequestAttributes();
if(requestAttribute != null){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
Map<String, String[]> paramMap = request.getParameterMap();
if(!paramMap.isEmpty()) {
params = " [" + paramMapToString(paramMap) + "]";
}
}
return params;
}
private String paramMapToString(Map<String, String[]> paramMap) {
return paramMap.entrySet().stream()
.map(entry -> String.format("%s -> (%s)",
entry.getKey(), Joiner.on(",").join(entry.getValue())))
.collect(Collectors.joining(", "));
}
}
4. ApiController.class
간단한 컨트롤러를 만들어 봅니다.
@RequiredArgsConstructor
@RestController
public class ApiController {
@GetMapping("/LoggingTest")
public String Logging(){
return "Logging Test Success";
}
}
5. 결과 확인
LoggingTest에 접속하게 되면 요청과 응답 로그가 출력되는 것을 확인할 수 있습니다.
궁금한 사항 또는 잘못된 사항이 있으면 댓글 남겨주세요!
'Spring' 카테고리의 다른 글
Autowire 알아보기 - 2 (0) | 2020.09.27 |
---|---|
Autowire 알아보기 - 1 (0) | 2020.09.27 |
Spring Web Layer 알아보기 (0) | 2020.07.12 |
SpringBoot - ExceptionHandler (1) | 2020.07.05 |
[토이 프로젝트] IT Article - 1 (0) | 2020.06.28 |