본문 바로가기
Study/Spring

[Spring] AOP 예제

by 나아가는 2023. 9. 25.
반응형

 

https://d2.naver.com/helloworld/3010710

AppRunner.java

  • ApplicationRunner를 상속 받은 클래스는 스프링이 실행될 때 (애플리케이션) run이 동작된다.
  • 스프링 부트에서 AOP 를 사용하기 위해서는 Java Bean에 등록을 해서 사용을 해야 한다.
  • Bean에 등록하기 위해서 Component 어노테이션을 붙여준다.
  • 저장된 Bean을 사용하기 위해 getBean과 비슷한 기능을 하는 Autowired 를 붙여준다
package kr.re.kitri.security.web.edu.exercise2.aop;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class AppRunner implements ApplicationRunner {
    @Autowired
    EventService es;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("무조건 실행");

        es.createEvent();
        es.publishEvent();
        es.deleteEvent();
    }
}

PerfAspect.java

  • @Aspect를 붙여주고, @Around(”execution(경로지정)”) 을 이용하여 적용할 point cut을 지정한다.
package kr.re.kitri.security.web.edu.exercise2.aop;

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

@Component
@Aspect
public class PerfAspect {
        // 메소드 호출 시간 측정
				@Around("execution(* kr.re.kitri.security.web.edu..*.EventService.*(..))")
		    //  @Around("@annotation(PerLogging)")
		    //  @Around("bean(simpleEventService)")
        
        public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
            long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed();  // 메소드 호출
        long end = System.currentTimeMillis();
        System.out.println("메소드 실행에 걸린 시간: " + (end - begin));

        return retVal;
    }
}

Point cut 지정 방식

  • 경로 지정 방식
    • @Around(”execution([경로])”)
  • 특정 어노테이션이 붙은 포인트에 지정
    • @Around(”@annotation([annotaionName])”)
  • 스프링 빈의 모든 메서드에 적용할 수 있는 기능
    • @Around("bean(beanName)").

API 적용 예제

controller/RestApiController.java

package kr.re.kitri.security.web.edu.exercise2.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestApiController {
    @GetMapping("/member-view")
    public String viewMember(){
        System.out.println("member-view GET API가 실행됨");
        return "member1";
    }
}

LogAspect.java > @Before나 After를 사용하려면 PointCut을 사용해야 한다

package kr.re.kitri.security.web.edu.exercise2.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAspect {
    @Pointcut("execution(* kr.re.kitri.security.web.edu.exercise2.controller..*.*(..))")
    private void logPointCut(){}

    @Before("logPointCut()")
    public void beforeLogAop(JoinPoint joinPoint){
        System.out.println("LogAop의 before가 실행됨");
    }
    @After("logPointCut()")
    public void afterLogAop(JoinPoint joinPoint){
        System.out.println("LogAop의 after가 실행됨");
    }
		@AfterReturning(value = "logPointCut()", returning = "returnObj")
    public void afterReturnLogAop(JoinPoint joinPoint, Object returnObj){
        System.out.println("LogAop의 afterReturn가 실행됨: " + joinPoint.toLongString());
        System.out.println("returnObj:" + returnObj);
    }
}
반응형