64.spring(7)

sumin·2023년 10월 11일
0

아카데미

목록 보기
65/82
post-thumbnail

AOP

AOP(Aspect Oriented Programming)
관점 지향 프로그래밍으로 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화 하는 것이다.

  1. AOP 관련 핵심 용어 3가지
    1) 조인포인트(JoinPoint) : AOP를 적용시킬 수 있는 메소드 전체이다. ex) 목록, 상세, 삽입, 수정, 삭제
    2) 포인트 컷(PointCut) : 조인 포인트 중에서 AOP를 동작시킬 메소드이다. ex) 삽입, 수정, 삭제
    3) 어드바이스(Advice) : 포인트 컷에 동작시킬 AOP 동작 자체 ex) 트랜잭션
  2. 어드바이스 동작 시점
    1) @Before : 포인트컷 동작 이전에 수행(인터셉터와 동일한 시점) (포인트컷 반환 타입: void)
    2) @After : 포인트컷 동작 이후에 수행 (포인트컷 반환 타입: void)
    3) @Around : 포인트컷 동작 이전/이후에 모두 수행 (포인트컷 반환 타입: Object 포인트컷의 실행 결과를 반환)
  3. 어드바이스 동작 순서
    @Around -> @Before -> @After
  4. 표현식(Expression) 작성 방법
    1) 형식
    execution(반환타입 패키지.클래스.메소드(매개변수))
    2) 의미
    (1) 반환타입
      ① * : 모든 반환타입
      ② void : void 반환타입
      ③ !void : void를 제외한 반환타입
    (2) 매개변수
      ① .. : 모든 매개변수
      ② * : 1개의 모든 매개변수

Around

@Slf4j
@Aspect
@Component
public class AroundAop {

  // 포인트컷 : 언제 동작하는가?
  @Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
  public void setPointCut() { }
  
  // 어드바이스 : 무슨 동작을 하는가?
  @Around("setPointCut()")
  public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
    /*
     * Around 어드바이스
     * 1. 반환타입 : Object
     * 2. 메소드명 : 마음대로
     * 3. 매개변수 : ProceedingJoinPoint
     */
       log.info("==================================================================");      // 포인트컷 실행 이전에 실행(@Before 이전에 동작)
    
    Object obj = proceedingJoinPoint.proceed();                                          // 포인트컷이 실행되는 시점
    
    log.info("{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));  // 포인트컷 실행 이후에 실행(@After 이전에 동작)
    
    return obj;   
  }
}

Before

@Slf4j  // private static final Logger log = LoggerFactory.getLogger(BeforeAop.class);
@Aspect
@Component
public class BeforeAop {

  // 포인트컷 : 언제 동작하는가?
  @Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
  public void setPointCut() { }  // 이름만 제공하는 메소드(이름은 마음대로 본문도 필요 없다.)
  
  // 어드바이스 : 무슨 동작을 하는가?
  @Before("setPointCut()")
  public void beforeAdvice(JoinPoint joinPoint) {
    
    /*
     * Before 어드바이스
     * 1. 반환타입 : void
     * 2. 메소드명 : 마음대로
     * 3. 매개변수 : JoinPoint
     */
    
    /* ContactController의 모든 메소드가 동작하기 전에 요청(방식/주소/파라미터) 출력하기 */
        
    // 1. HttpServletRequest
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = servletRequestAttributes.getRequest();
    
    // 2. 요청 파라미터 -> Map 변환
    Map<String, String[]> map = request.getParameterMap();
    
    // 3. 요청 파라미터 출력 형태 만들기
    String params = "";
    if(map.isEmpty()) {
      params += "No Parameter";
    } else {
      for(Map.Entry<String, String[]> entry : map.entrySet()) {
        params += entry.getKey() + ":" + Arrays.toString(entry.getValue()) + " ";
      }
    }
    
    // 4. 로그 찍기 (치환 문자 {} 활용)
    log.info("{} {}", request.getMethod(), request.getRequestURI());  // 요청 방식, 요청 주소
    log.info("{}", params);                                           // 요청 파라미터
    
  }
  
}

After

@Slf4j
@Aspect
@Component
public class AfterAop {

  // 포인트컷 : 언제 동작하는가?
  @Pointcut("execution(* com.gdu.app10.controller.*Controller.*(..))")
  public void setPointCut() { }
  
  // 어드바이스 : 무슨 동작을 하는가?
  @After("setPointCut()")
  public void afterAdvice(JoinPoint joinPoint) {
    
    /*
     * After 어드바이스
     * 1. 반환타입 : void
     * 2. 메소드명 : 마음대로
     * 3. 매개변수 : JoinPoint
     */
    
    // 로그 찍기
    log.info("==================================================================");  
  } 
}

ServiceImpl

Controller

@After @Before @ Around 를 붙인 곳에서는
After Before Around
와 같이 쪽에 화살표가 붙는다.

profile
백엔드 준비생의 막 블로그

0개의 댓글