스프링 AOP: @AOP

1. Spring AOP 설정 코드

PerfAspect.java

@Component
@Aspect
public class PerfAspect {

    // logPerf 함수 : AOP의 advice(해야 할 일)에 해당함.
    // pjp : advice가 적용되는 대상 (Ex: createEvent, publishEvent)
    // @Around : advice를 어떻게 적용할 것인가. 메서드를 감싸는형태로 적용됨, 메서드 호출 이전 이후 Exception 시에도 특정한 일을 할 수 있다.
    // @Around("execution(* me.hyunki..*.EventService.*(..))") -> EventService 안에 있는 모든 메서드에 아래의 행위를 적용 하라는 뜻 (PointCut을 정의함)
    // @Around("bean(simpleEventService)") : bean을 사용 -> 해당 bean의 모든 메서드에 적용되어 버리는 단점
    @Around("@annotation(PerfLogging)") // deleteEvent에는 적용하고 싶지 않기 때문에 어노테이션이 있는 곳에만 실행 되게끔 설정함. (이게 가장 유용함)
    //원본 코드에 수정이나 추가 없이 많은 클래스에 아래의 행위를 끼워 넣을수 있다.
    public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed(); //메서드 실행
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
    }

    //모든 메서드 실행 이전에 hello가 찍힘
    @Before("bean(simpleEventService)")
    public void hello() {
        System.out.println("hello");
    }
}

PerfLogging.java

/**
 * 이 에노테이션을 사용하면 성능을 로깅해 줍니다.
 */

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS) //기본 값이 클래스
public @interface PerfLogging {
}

EventService.java

public interface EventService {

    void createEvent();

    void publishEvent();

    void deleteEvent();
}

SimpleEventService.java

@Service
public class SimpleEventService implements EventService{

    @PerfLogging
    @Override
    public void createEvent() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Created an event");
    }

    @PerfLogging
    @Override
    public void publishEvent() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Published an event");
    }

    public void deleteEvent() {
        System.out.println("Delete an event");
    }
}

AppRunner.java

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    EventService eventService; // Interface가 있는 경우에는 Interface다 타입으로 주입 받는게 가장 좋음

    @Override
    public void run(ApplicationArguments args) throws Exception {
        eventService.createEvent();
        eventService.publishEvent();
        eventService.deleteEvent();
    }
}
  • AOP를 적용하게 되면, IDE에 AOP 관련 표시가 나오게 됨.
  • PerfLogging.java로 에노테이션을 직접 만들어서 해당 에노테이션이 붙은 부분에만 AOP가 적용되게끔 하는 방법이 가장 유용하고 좋다.

2. 강의노트

애노테이션 기반의 스프링 @AOP

의존성 추가

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

애스팩트 정의

  • @Aspect
  • 빈으로 등록해야 하니까 (컴포넌트 스캔을 사용한다면) @Component도 추가.

포인트컷 정의

  • @PointCut(표현식)
  • 주요 표현식
    • execution
    • @annotation
    • bean
  • 포인트컷 조합
    • &&,||, !

어드바이스 정의

  • @Before
  • @AfterReturning
  • @AfterThrowing
  • @Around

참고

좋은 웹페이지 즐겨찾기