스프링 AOP: 프록시 기반 AOP

맹기·2021년 4월 21일
0

Spring 핵심 기술 원리

목록 보기
18/19

1. 기존 Proxy 패턴의 코드와 그 문제점

  • Proxy 패턴 구조

    • 왜 사용?? : 접근 제어 또는 부가 기능 추가
  • 예시 코드 및 Porxy 패턴의 문제점

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();
    }
}

EventService.java

public interface EventService {

    void createEvent();

    void publishEvent();

    void deleteEvent();
}

SimpleEventService.java

@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 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");
    }
}

ProxySimpleEventService.java

@Primary // 이 설정으로 인해 EventService를 다른 곳에서 주입받게 되면 이 빈을 주입 받게 된다.
@Service
public class ProxySimpleEventService implements EventService{

    @Autowired
    SimpleEventService simpleEventService; //Proxy는 Subject의 빈을 주입받아 사용해야함.
    //EventService simpleEventService; // 이것도 가능

    @Override
    public void createEvent() {
        long begin = System.currentTimeMillis();
        simpleEventService.createEvent();
        System.out.println(System.currentTimeMillis() - begin);
    }

    @Override
    public void publishEvent() {
        long begin = System.currentTimeMillis();
        simpleEventService.publishEvent();
        System.out.println(System.currentTimeMillis() - begin);
    }

    @Override
    public void deleteEvent() {
        simpleEventService.deleteEvent();
    }
}

문제점
1. 메서드 실행 시간을 측정하고 싶을 경우에 아래의 코드를 모든 메서드마다 삽입해야하는 문제가 있음.

long begin = System.currentTimeMillis();
System.out.println(System.currentTimeMillis() - begin);
  1. Proxy 클래스를 만드는데 드는 비용과 수고 + 모든 메서드를 델리게이션 해줘야함.
  2. 해당 기능이 다른 Proxy나 다른 클래스에 적용해야 된다고 생각하면 중복된 코드가 엄청 많아지며 비효율적이게 됨

-> 이러한 문제점 들을 스프링 AOP가 해결을 해준다고 함

2. 강의노트

스프링 AOP 특징

  • 프록시 기반의 AOP 구현체
  • 스프링 빈에만 AOP를 적용할 수 있다.
  • 모든 AOP 기능을 제공하는 것이 목적이 아니라, 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 제공하는 것이 목적.

프록시 패턴

  • 왜?(기존 코드 변경 없이) 접근 제어 또는 부가 기능 추가
  • 기존 코드를 건드리지 않고 성능 측정(프록시 패턴으로)

문제점

  • 매번 프록시 클래스를 작성해야 하는가?
  • 여러 클래스 여러 메소드에 적용하려면?
  • 객체들 관계도 복잡하고...

그래서 등장한 것이 스프링 AOP

  • 스프링 IoC 컨테이너가 제공하는 기반 시설과 Dynamic 프록시를 사용하여 여러 복잡한 문제 해결.
  • 동적 프록시 : 동적으로 프록시 객체 생성하는 방법
    • 자바가 제공하는 방법은 인터페이스 기반 프록시 생성.
    • CGlib은 클래스 기반 프록시도 지원.
  • 스프링 IoC: 기존 빈을 대체하는 동적 프록시 빈을 만들어 등록 시켜준다.
    • 클라이언트 코드 변경 없음.
    • AbstractAutoProxyCreator implements BeanPostProcessor

0개의 댓글

관련 채용 정보