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);
- Proxy 클래스를 만드는데 드는 비용과 수고 + 모든 메서드를 델리게이션 해줘야함.
- 해당 기능이 다른 Proxy나 다른 클래스에 적용해야 된다고 생각하면 중복된 코드가 엄청 많아지며 비효율적이게 됨
-> 이러한 문제점 들을 스프링 AOP가 해결을 해준다고 함
스프링 AOP 특징
프록시 패턴
문제점
그래서 등장한 것이 스프링 AOP