본문 바로가기

개발/Spring

AOP - 프록시 기반 AOP

반응형

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

프록시 패턴
 - 왜 ? (기존 코드 변경 없이) 접근 제어 또는 부가 기능 추가 
 - 기존 코드를 건드리지 않고 일을 끼워넣기!

소스코드
 - 구현할 함수를 정의한 인터페이스

package com.bpkim.demospring51;

public interface EventService {

    void createEvent();

    void publishEvent();

    void deleteEvent();
}

 - 인터페이스를 상속하여 할 일을 선언한 Serive 클래스

package com.bpkim.demospring51;

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

- 프록시 패턴 적용

package com.bpkim.demospring51;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

@Primary
@Service
public class ProxySimpleEventService implements EventService {

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

- 결과 확인을 위한 AppRunner 

package com.bpkim.demospring51;

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.publishEvent();
        eventService.deleteEvent();
    }
}

- 실행 결과 

>> 프록시 패턴을 이용해 SimpleEventService에 선언한 함수를 수정하지 않고
     실행 시간 측정 기능 추가 

그러나 문제점이 있다!
 - 매번 프록시 클래스를 작성해야한다.
   할 일을 정의한 클래스 마다 프록시 클래스를 작성해야한다...
 - 여러 클래스 여러 메소드에 적용하려면..
  여러개의 클래스와 여러개의 메소드를 만들어야 겠지..
 - 객체의 관계가 복잡..
  인터페이스  > 구현할 클래스 > 구현할 클래스를 이용한 프록시 패턴 클래스 ... 너무 복잡하다.

>>>> 그래서 스프링에는 스프링 AOP가 있다!!
 - 스프링 IoC 컨테이너가 제공하는 기반 시설과 Dynamic 프록시를 사용하여 여러 복잡한 문제 해결
 - 동적 프록시 : 동적 프록시 객체 생성
 - 스프링 IoC : 기존 빈을 대체하는 동적 프록시 빈을 만들어 등록시켜준다.


반응형

'개발 > Spring' 카테고리의 다른 글

Null-Safety  (0) 2021.04.27
AOP - @AOP  (0) 2021.04.27
스프링 AOP - 개념  (0) 2021.04.27
SpEL(스프링 Expression Language)  (0) 2021.04.23
데이터 바인딩 추상화 Converter와 Formatter  (0) 2021.04.23