반응형
AOP DI 추가
implementation 'org.springframework.boot:spring-boot-starter-aop'
controller
@Slf4j
@RestController
@RequestMapping("/api")
public class RestApiController {
@GetMapping("/get/{id}")
public String get(@PathVariable Long id, @RequestParam String name){
return String.format("%s-%s",id, name);
}
@PostMapping("/post")
public UserDto post(@RequestBody UserDto userDto){
return userDto;
}
@Decode
@PutMapping("/put")
public UserDto put(@RequestBody UserDto userDto){
log.info("put: {}",userDto);
return userDto;
}
@Timer
@DeleteMapping("/delete")
public void delete() throws InterruptedException {
Thread.sleep(2000);
}
}
특정 클래스 메서드 실행 전 후 로깅 AOP 컴포넌트 생성
@Slf4j
@Aspect
@Component
public class ApiParamAop {
//controller 하위 모든 메서드
@Pointcut("execution(* com.wooriworld.controller..*.*(..))")
private void myPointCut() {
}
//포인트 컷 의 하위 메서드 실행 전
@Before("myPointCut()")
public void before(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
log.info("method: {}", method.getName());
for(Object obj : args) {
log.info("Type: {}, ", obj.getClass().getSimpleName());
log.info("value: {}, ", obj);
}
}
//리턴 오브젝트 파라미터이름과 일치 해야 한다.
////포인트 컷 의 하위 메서드 실행 후
@AfterReturning(value = "myPointCut()", returning = "returnObj")
public void afterReturn(JoinPoint joinPoint, Object returnObj) {
log.info("return obj: {}", returnObj);
}
/*
//해당 메서드가 예외 발생시 실행
@AfterThrowing(value = "myPointCut()", returning = "returnObj")
public void afterReturn(JoinPoint joinPoint, Object returnObj) {
log.info("return obj: {}", returnObj);
}
*/
}
어노테이션 기반 타이머 AOP 생성
타이머 어노테이션 생성
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
타이머 AOP 생성
@Slf4j
@Aspect
@Component
public class TimerAop {
//controller 하위 모든 것
@Pointcut("execution(* com.wooriworld.controller..*.*(..))")
private void myPointCut() {
}
@Pointcut("@annotation(com.wooriworld.annotation.Timer)")
private void enableTimer(){
}
//두가지 조건을 같이 사용 한다.
@Around("myPointCut() && enableTimer()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.prettyPrint();
stopWatch.start();
Object result = joinPoint.proceed();
//실행 후
stopWatch.stop();
log.info("Total Time: {}", stopWatch.getTotalTimeSeconds());
}
}
어노테이션 기반 디코딩 AOP
디코딩 어노테이션 생성
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Decode {
}
디코딩 AOP 생성
@Slf4j
@Aspect
@Component
public class DecodeAop {
//controller 하위 모든 것
@Pointcut("execution(* com.wooriworld.controller..*.*(..))")
private void myPointCut() {
}
@Pointcut("@annotation(com.wooriworld.annotation.Decode)")
private void enableDecode(){
}
@Before("myPointCut() && enableDecode()")
public void before(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
for(Object obj: args) {
if(obj instanceof UserDto) {
UserDto user = UserDto.class.cast(obj);
String email = user.getEmail();
user.setEmail(new String(Base64.getDecoder().decode(email.getBytes(StandardCharsets.UTF_8))));
}
}
}
@AfterReturning(value = "myPointCut() && enableDecode()", returning = "returnObj")
public void afterReturn(JoinPoint joinPoint, Object returnObj){
if(returnObj instanceof UserDto) {
UserDto user = UserDto.class.cast(returnObj);
String email = user.getEmail();
user.setEmail(new String(Base64.getEncoder().encode(email.getBytes(StandardCharsets.UTF_8))));
}
}
}
샘플 코드: github
반응형
'SpringBoot' 카테고리의 다른 글
Unit Test - ParameterizedTest (0) | 2022.05.21 |
---|---|
Java Conditional Unit Test (0) | 2022.05.21 |
Spring mvc async rest api (0) | 2021.11.07 |
Spring mvc async rest api (0) | 2021.11.07 |
java excell downloader in spring boot (0) | 2021.10.31 |