개요
mapping 되어있는 post, get으로 들어올 때 @RequestParam 또는 @RequestBody로 들어오는 데이터를 받아오는데 들어오는 것을 무조건 로그로 찍어내는 AOP를 만들러 보았다.
설명
- AOP
1. Aspect : 어플리케이션에서 공통적으로 발생하는 작업을 구현한 모듈
Aspect의 구현은 xml, java를 이용하여 configuration 할수 있다....
<!-- advisor 설정한 Class bean 등록 -->
<bean id='advisorTest' class='com.victory.advisor.AdvisorTest'/>
<!-- AOP 설정 -->
<aop:config>
<!-- advisor Class aspect conig 설정-->
<aop:aspect ref='advisorTest'>
<!-- pointcut 시점 설정-->
<aop:pointcut id="pointcutTest" expression="execution(* com.victory..*Controller.*(..))"/>
<!-- pointcut에서 시행할 method 설정-->
<aop:before method="beforeTest" pointcut-ref="pointcutTest"/>
</aop:aspect>
</aop:config>
...
- java
@EnableAspectJAutoProxy
@Aspect
@Component
public class AdvisorTest {
@Before("execution(* com.victory..*Controller.*(..))")
public Object beforeTest(JoinPoint joinpoint) throws Throwable {
return joinpoint;
}
}
2. Advice: Join Point에서 수행되는 작업
3. Join Point : 어플리케이션 실행 중에 공통 작업이 삽입될 수 있는 지점
4. Pointcut: Join Point의 집합으로, Advice가 적용될 지점을 결정
5. Weaving: Aspect를 핵심 비즈니스 로직에 적용하는 과정
구현
spring aop를 이용하여 @Arround를 이용하여 project안에 *Controller안에 있는 method들이 시작될 때 해당 proceedingJoinPoint를 가져와 로그를 찍고 method가 실행되고 반환되는 값도 로그를 찍을 것이다.
@Arround는 중간에 메서드가 실행하는 부분이 있어서 proceedingJoinPoint를 매개변수로 쓰고
나머지는 JoinPoint를 매개변수로 사용한다.
pom.xml에 spring aop 의존성 추가
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
...
java config
@Slf4j
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
// @Arroud전후작업에 모두 사용
// 적용할 메서드를 명시 리턴패턴 패키지안에 *Contorller에있는 모든 메소드 해당 메소드에 있는 매개변수 불러오기
// execution (* com.victory..*Controller.*(..) && args(params,..)
@Around("execution(* com.victory..*Controller.*(..)) && args(params,..)")
public Object logBefore(ProceedingJoinPoint joinpoint, Map<String, Object> params) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
//HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
log.info("==== ReqParam : " + params);
//메소드 실행 (joinpoint.proceed()을 안하면설정한 메소드들은 실행을 안한다.)
Object proceed = joinpoint.proceed();
Map<String, Object> resMap = new HashMap<>();
if (proceed instanceof Map) {
//
resMap.put("resultValue", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(proceed));
} else {
resMap.put("resultValue", proceed);
}
log.info("==== ResParam : " + resMap.get("resultValue"));
return proceed;
}
}
Controller
...
@PostMapping("/test")
public Map<String, Object> test(@RequestBody @Parameter Map<String, Object> param) throws Exception {
log.debug("param : ", param);
Map<String, Object> result = new HashMap<>();
result.put("resultKey","resultValue");
return result;
}
...
/test를 호출하면 로그에 잘 나오는 것을 확인할 수 있다.
https://github.com/victory940209/testspringboot/tree/main/simpleSpringboot
GitHub - victory940209/testspringboot
Contribute to victory940209/testspringboot development by creating an account on GitHub.
github.com
'Spring' 카테고리의 다른 글
Spring Validation (@Valid, @Validated) (0) | 2023.03.17 |
---|---|
Swagger 3.x 와 spring doc [2] (0) | 2023.03.15 |
Swagger 3.x 와 spring doc [1] (0) | 2023.03.14 |