스프링 AOP 특징
- 프록시 기반의 기반의 AOP 구현체
- 스프링 빈에만 AOP를 적용할 수 있다.
- 모든 AOP 기능을 제공하는 것이 목적이 아니라, 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 제공하는 것이 목적.
프록시 패턴
왜 쓰는가?
(기존 코드 변경 없이) 접근 제어 또는 부가 기능 추가
Client
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
EventService eventService ;
@Override
public void run(ApplicationArguments args) throws Exception {
eventService.publishEvent();
eventService.createEvent();
}
}
Subject
public interface EventService {
void createEvent();
void publishEvent();
}
RealSubject
@Service
public class SimpleEventService implements EventService{
@Override
public void createEvent() {
long begin = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Create an event!");
System.out.println("createEvent 실행시간: "+(System.currentTimeMillis()-begin));
}
@Override
public void publishEvent() {
long begin = System.currentTimeMillis();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Published an event!");
System.out.println("publishEvent 실행시간: "+(System.currentTimeMillis()-begin));
}
@Override
public void deleteEvent() {
System.out.println("Delete an event!");
}
}
이때 RealSubject의 코드를 건드리지 않고 createEvent, publicEvent 메서드의 실행시간을 측정하는 Proxy를 생성해보자!
- ProxySimpleEventService 프록시 클래스 생성
- 리얼 서브젝트와 동일한 인터페이스를 구현한다.
- 리얼 서브젝트를 참조
@Primary
@Service
public class ProxySimpleEventService implements EventService{
@Autowired
EventService simpleEventService;
// SimpleEventService simpleEventService;
// SimpleEventService simpleEventService;
//
// ProxySimpleEventService(SimpleEventService simpleEventService) {
// this.simpleEventService = simpleEventService;
// }
@Override
public void createEvent() {
long begin = System.currentTimeMillis();
simpleEventService.createEvent();
System.out.println("createEvent 실행시간: "+(System.currentTimeMillis()-begin));
}
@Override
public void publishEvent() {
long begin = System.currentTimeMillis();
simpleEventService.publishEvent();
System.out.println("createEvent 실행시간: "+(System.currentTimeMillis()-begin));
}
@Override
public void deleteEvent() {
simpleEventService.deleteEvent();
}
}
리얼 서브젝트에 있는 실행시간 측정 내용을 Proxy 클래스로 위임
문제점 발생
1. 중복된 코드 발생
2. Proxy클래스를 만드는데 cost가 든다.
그래서 등장한 것이 스프링 AOP
- 스프링 IoC 컨테이너가 제공하는 기반 시설과 Dynamic 프록시를 사용하여 여러 복잡한 문제 해결.
- 동적 프록시: 동적으로 프록시 객체 생성하는 방법
- 자바가 제공하는 방법은 인터페이스 기반 프록시 생성.
- CGlib은 클래스 기반 프록시도 지원.
- 스프링 IoC: 기존 빈을 대체하는 동적 프록시 빈을 만들어 등록시켜준다.
클라이언트 코드 변경 없음.
AbstractAutoProxyCreator implements BeanPostProcessor
SimpleEventServcie가 빈으로 등록될때 AbstractAutoProxyCreator라는 빈 포스트 프로세서로
해당 bean을 감싸는 proxy bean을 만들어서 해당 bean을 SimpleEventServcie대신에 등록한다.
https://jwdeveloper.tistory.com/47
코드 참고
https://github.com/mike6321/Spring/tree/master/Spring/AOP
'Spring > Spring' 카테고리의 다른 글
(SPRING) IoC 컨테이너 - 스프링 IoC 컨테이너와 빈 (0) | 2019.12.31 |
---|---|
(SPRING) 스프링 AOP : 애노테이션 기반 AOP (0) | 2019.12.25 |
(SPRING) 스프링 웹 애플리케이션 제거방법 (0) | 2019.12.25 |
(SPRING) AOP(Aspect-Oriented-Programming) (0) | 2019.12.24 |
(SPRING) 오브젝트와 의존관계 (스프링에 IOC) (0) | 2019.12.09 |