Christmas Pikachu SpringBoot 어노테이션 만들어 AOP 활용하기
개발일지/스프링

SpringBoot 어노테이션 만들어 AOP 활용하기

ZI_CO 2022. 12. 7.

User Dto

package com.example.demo.dto;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class User {

	private Long id;
	private String email;
	private String pw;
}

 

ApiController

package com.example.demo.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.anno.Timer;
import com.example.demo.dto.User;

@RestController
@RequestMapping("/api/user")
public class ApiController {

	@Timer
	@GetMapping("/get/{id}")
	public String get(@PathVariable Long id, @RequestParam String name) {
		return id + "," + name;
	}
	// http://localhost:8080/api/user/post
		@PostMapping("/post")
		public ResponseEntity<User> post(@RequestBody User user) {
			
			//만약 AOP를 쓰지 않는다면 직접 메소드마다 코드를 추가해야한다.
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();
			
			// 핵심 로직 ~ ~ (서비스 --> DB처리 등등)
			
			try {
				Thread.sleep(3500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			stopWatch.stop();
			System.err.println("걸린 시간 측정 : " + stopWatch.getTotalTimeSeconds());
			
			return ResponseEntity.status(HttpStatus.OK).body(user);
			
		}
		
		// http://localhost:8080/api/user/delete
		@Timer
		@DeleteMapping("/delete")
		public void delete() throws InterruptedException {
			// db logic...
			Thread.sleep(2000);
			
		}

}

 

 

TimerAop

package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class TimerAop {

	//Pointcut 여러개 사용 가능
	@Pointcut(value = "execution(* com.example.demo.controller..*.*(..))")
	public void cut() {}
	
	@Pointcut(value = "@annotation(com.example.demo.anno.Timer)")
	private void checkTimer() {}
	
	@Around("cut() && checkTimer()")
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		//시간 측정
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		// 실행 전
		Object result = proceedingJoinPoint.proceed();
		// 메서드 실행 완료
		stopWatch.stop();
		System.out.println("total time: "+stopWatch.getTotalTimeSeconds());
		
	}
	
}

 

 

Timer (직접 만든 어노테이션)

package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class TimerAop {

	//Pointcut 여러개 사용 가능
	@Pointcut(value = "execution(* com.example.demo.controller..*.*(..))")
	public void cut() {}
	
	@Pointcut(value = "@annotation(com.example.demo.anno.Timer)")
	private void checkTimer() {}
	
	@Around("cut() && checkTimer()")
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		//시간 측정
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		// 실행 전
		Object result = proceedingJoinPoint.proceed();
		// 메서드 실행 완료
		stopWatch.stop();
		System.out.println("total time: "+stopWatch.getTotalTimeSeconds());
		
	}
	
}

 

댓글