오봉이와 함께하는 개발 블로그
스프링 핵심 원리 - 고급편 > 구체 클래스 기반 프록시 적용 본문
728x90
스프링 핵심 원리 - 고급편 > 구체 클래스 기반 프록시 적용
실제 적용을 해보자.
@RequiredArgsConstructor
public class OrderRepositoryConcreteProxy extends OrderRepositoryV2 {
private final OrderRepositoryV2 orderRepositoryV2;
private final LogTrace logTrace;
@Override
public void save(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("orderRepositoryV2.save");
orderRepositoryV2.save(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
public class OrderServiceConcreteProxy extends OrderServiceV2 {
private final OrderServiceV2 orderServiceV2;
private final LogTrace logTrace;
public OrderServiceConcreteProxy(OrderServiceV2 orderServiceV2, LogTrace logTrace) {
super(null);
this.orderServiceV2 = orderServiceV2;
this.logTrace = logTrace;
}
@Override
public void orderItem(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderService.orderItem()"); //target 호출
orderServiceV2.orderItem(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
public class OrderControllerConcreteProxy extends OrderControllerV2 {
private final OrderControllerV2 orderControllerV2;
private final LogTrace logTrace;
public OrderControllerConcreteProxy(OrderControllerV2 orderControllerV2, LogTrace logTrace) {
super(null);
this.orderControllerV2 = orderControllerV2;
this.logTrace = logTrace;
}
@Override
public String request(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderControllerProxy.request()");
String result = orderControllerV2.request(itemId);
logTrace.end(status);
return result;
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
@Override
public String noLog() {
return orderControllerV2.noLog();
}
}
@Configuration
public class ConcreteProxyConfig {
@Bean
public OrderControllerV2 orderController(LogTrace logTrace) {
OrderControllerV2 orderControllerV2 = new OrderControllerV2(orderService(logTrace));
return new OrderControllerConcreteProxy(orderControllerV2, logTrace);
}
@Bean
public OrderServiceV2 orderService(LogTrace logTrace) {
OrderServiceV2 orderServiceV2 = new OrderServiceV2(orderRepository(logTrace));
return new OrderServiceConcreteProxy(orderServiceV2, logTrace);
}
@Bean
public OrderRepositoryV2 orderRepository(LogTrace logTrace) {
OrderRepositoryV2 orderRepositoryV2 = new OrderRepositoryV2();
return new OrderRepositoryConcreteProxy(orderRepositoryV2, logTrace);
}
}
크게 어려운 코드는 없지만 단점이 보인다.super(null)
은 자바 기본 문법에 의해 자식 클래스를 생성할 때는 항상 super()로 부모 클래스의 생성자를 호출해주어야만 한다. 이 부분을 생략하면 기본 생성자가 호출되는데, 부모 클래스에 기본 생성자가 없고 생성자에서 파라미터 1개를 필수로 받고 있다.
따라서 super(params...)를 호출해야 한다.
프록시는 부모 객체의 기능을 사용하지 않기 때문에 super(null)을 해도 된다.
단, super.someMethod()
와 같이 부모 객체의 기능을 사용할 경우는 필요할 것이다.
참고로 OrderServiceV2의 생성자는 아래와 같다.
public OrderServiceV2(OrderRepositoryV2 orderRepository) {
this.orderRepository = orderRepository;
}
출처: 김영한 지식공유자의 스프링 핵심 원리 고급편
728x90
'BE > Spring' 카테고리의 다른 글
스프링 핵심 원리 - 고급편 > 리플렉션 (0) | 2024.08.28 |
---|---|
스프링 핵심 원리 - 고급편 > 인터페이스 기반 vs 클래스 기반 프록시 정리 (0) | 2024.08.27 |
스프링 핵심 원리 - 고급편 > 구체 클래스 기반 프록시 (0) | 2024.08.27 |
스프링 핵심 원리 - 고급편 > 인터페이스 기반 프록시 적용 (0) | 2024.08.27 |
스프링 핵심 원리 - 고급편 > 프록시 패턴과 데코레이터 패턴 정리 (0) | 2024.08.25 |
Comments