Spring AOP : @AOP

AOP 애노테이션을 사용하기 위해서는 pom.xml에 먼저 의조성을 설정해줘야 한다.

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

 

| 애노테이션 개반의 스프링AOP 적용 방법

package com.kyhslam.demo;

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 eventService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        eventService.createEvent();
        eventService.publishEveent();
        eventService.deleteEvent();
    }
}
package com.kyhslam.demo;

public interface EventService {

    void createEvent();

    void publishEveent();

    void deleteEvent();
}
package com.kyhslam.demo;

import org.springframework.stereotype.Service;

@Service
public class SimpleEventService implements EventService {

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

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

    @Override
    public void deleteEvent() {
        System.out.println("DeleteEvent as event");
    }
}
package com.kyhslam.demo;


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 {

    // com.kyhslam밑에 있는 모든 클래스 중에 EventService안에 들어있는 모든 메서드에 적용해라
    @Around("execution(* com.kyhslam..*.EventService.*(..))")
    public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
    }
}

결과

Created an event
1027
Published as event
2009
DeleteEvent as event

EventService안에 있는 모든 메서드에 적용된 것을 확인할 수 있다.

그러나 만약에 애노테이션 기반으로 DeleteEvent메서드를 제외한 특정 메서드에만 적용할 수 있다.

| 특정 메서드에만 AOP 적용

package com.kyhslam.demo;

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("@annotation(PerLogging)")
    public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        System.out.println(System.currentTimeMillis() - begin);
        return retVal;
    }
}
package com.kyhslam.demo;

import java.lang.annotation.*;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface PerLogging {
}
package com.kyhslam.demo;

import org.springframework.stereotype.Service;

@Service
public class SimpleEventService implements EventService {

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


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

    @Override
    public void deleteEvent() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("DeleteEvent as event");
    }
}

SimpleEventService 메서드를 보면 적용할 메서드에 @PerLogging 애노테이션을 명시해 주면 된다.

실행 결과

Created an event
1013
Published as event
2010
DeleteEvent as event

DeleteEvent 메서드에는 AOP가 적용되지 않은 것을 볼 수 있다.

댓글

Designed by JB FACTORY