Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 그리디
- 자바
- Proxy
- SpringBoot
- 인프런
- QueryDSL
- jpa
- 백준
- db
- transaction
- kotlin
- 스프링 핵심 원리
- AOP
- 스프링 핵심 기능
- 스프링
- spring
- Android
- Exception
- springdatajpa
- 김영한
- Servlet
- http
- Thymeleaf
- 알고리즘
- Spring Boot
- JPQL
- Greedy
- pointcut
- java
- JDBC
Archives
- Today
- Total
개발자되기 프로젝트
구체 클래스 기반 프록시 - 적용 본문
구체 클래스만 있는 V2에 적용해 보자.
1. OrderRepositoryConcreteProxy
@Slf4j
public class OrderRepositoryConcreteProxy extends OrderRepositoryV2 {
private final OrderRepositoryV2 target;
private final LogTrace logTrace;
public OrderRepositoryConcreteProxy(OrderRepositoryV2 target, LogTrace logTrace) {
this.target = target;
this.logTrace = logTrace;
}
@Override
public void save(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("[Proxy] OrderRepository.request()");
//target 호출
target.save(itemId);
logTrace.end(status);
}catch (Exception e){
logTrace.exception(status, e);
throw e;
}
}
}
2. OrderServiceConcreteProxy
@Slf4j
public class OrderServiceConcreteProxy extends OrderServiceV2 {
private final OrderServiceV2 target;
private final LogTrace logTrace;
//부모 클래스에서 기본 생성자 외에 다른 생성자가 있는 경우
//자식 클래스에서 부모 클래스의 생성자를 호출해 줘야함.
public OrderServiceConcreteProxy( OrderServiceV2 target, LogTrace logTrace) {
//기본 생성자를 호출하거나, 다른 생성자를 호출해야 하는 상황.
//부모클래스의 기본 생성자는 없고, 해당 생성자를 이용하지도 않음. proxy역할만 함.
//super에 null을 넘겨주자.
super(null);
this.target = target;
this.logTrace = logTrace;
}
@Override
public void orderItem(String itemId) {
super.orderItem(itemId);
}
}
3. 클래스 기반 프록시의 단점
- super(null) : OrderServiceV2 : 자바 기본 문법에 의해 자식 클래스를 생성할 때는 항상 super() 로
부모 클래스의 생성자를 호출해야 한다. - 이 부분을 생략하면 기본 생성자가 호출된다. -> super(...) 생략하면 자동으로 super() 호출됨.
- 그런데 부모 클래스인 OrderServiceV2 는 기본 생성자가 없고, 생성자에서 파라미터 1개를 필수로 받는다.
- 따라서 파라미터를 넣어서 super(..) 를 호출해야 한다.
- 프록시는 부모 객체의 기능을 사용하지 않기 때문에 super(null) 을 입력해도 된다.
- 인터페이스 기반 프록시는 이런 고민을 하지 않아도 된다.
4. OrderControllerConcreteProxy
@Slf4j
public class OrderControllerConcreteProxy extends OrderControllerV2 {
private final OrderControllerV2 target;
private final LogTrace logTrace;
public OrderControllerConcreteProxy(OrderControllerV2 target, LogTrace logTrace) {
super(null);
this.target = target;
this.logTrace = logTrace;
}
@Override
public String request(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("[Proxy] OrderController.request()");
//target 호출
String result = target.request(itemId);
logTrace.end(status);
return result;
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
@Override
public String noLog() {
return target.noLog();
}
}
5. OrderServiceConcreteProxy
@Slf4j
public class OrderServiceConcreteProxy extends OrderServiceV2 {
private final OrderServiceV2 target;
private final LogTrace logTrace;
//부모 클래스에서 기본 생성자 외에 다른 생성자가 있는 경우
//자식 클래스에서 부모 클래스의 생성자를 호출해 줘야함.
public OrderServiceConcreteProxy( OrderServiceV2 target, LogTrace logTrace) {
//기본 생성자를 호출하거나, 다른 생성자를 호출해야 하는 상황.
//부모클래스의 기본 생성자는 없고, 해당 생성자를 이용하지도 않음. proxy역할만 함.
//super에 null을 넘겨주자.
super(null);
this.target = target;
this.logTrace = logTrace;
}
@Override
public void orderItem(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("[Proxy] OrderService.orderItem()");
//target 호출
target.orderItem(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
6. OrderRepositoryConcreteProxy
@Slf4j
public class OrderRepositoryConcreteProxy extends OrderRepositoryV2 {
private final OrderRepositoryV2 target;
private final LogTrace logTrace;
public OrderRepositoryConcreteProxy(OrderRepositoryV2 target, LogTrace logTrace) {
this.target = target;
this.logTrace = logTrace;
}
@Override
public void save(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("[Proxy] OrderRepository.request()");
//target 호출
target.save(itemId);
logTrace.end(status);
}catch (Exception e){
logTrace.exception(status, e);
throw e;
}
}
}
7. Configuration
@Configuration
public class ConcreteProxyConfig {
@Bean
public OrderControllerV2 orderControllerV2(LogTrace logTrace){
OrderControllerV2 controllerImpl = new OrderControllerV2(orderServiceV2(logTrace));
return new OrderControllerConcreteProxy(controllerImpl, logTrace);
}
@Bean
public OrderServiceV2 orderServiceV2(LogTrace logTrace){
OrderServiceV2 serviceImpl = new OrderServiceV2(orderRepositoryV2(logTrace));
return new OrderServiceConcreteProxy(serviceImpl, logTrace);
}
@Bean
public OrderRepositoryV2 orderRepositoryV2(LogTrace logTrace){
OrderRepositoryV2 repositoryImpl = new OrderRepositoryV2();
return new OrderRepositoryConcreteProxy(repositoryImpl,logTrace);
}
}
8. 실행
@Import(ConcreteProxyConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app") //주의
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Bean
public LogTrace logTrace(){
return new ThreadLocalLogTrace();
}
}
[79fe5b00] [Proxy] OrderController.request()
[79fe5b00] |-->[Proxy] OrderService.orderItem()
[79fe5b00] [Proxy] OrderController.request() time=1002ms
[79fe5b00] | |-->[Proxy] OrderRepository.request()
[79fe5b00] | |<--[Proxy] OrderRepository.request() time=1001ms
[79fe5b00] |<--[Proxy] OrderService.orderItem() time=1001ms
9. GitHub : 211230 Concrete Class기반 Proxy 2
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
[동적프록시] 리플렉션 (0) | 2021.12.30 |
---|---|
인터페이스기반 프록시와 클래스 기반 프록시 (0) | 2021.12.30 |
구체 클래스 기반 프록시 - 예제 (0) | 2021.12.29 |
Interface기반 Proxy - 적용 (0) | 2021.12.29 |
Proxy Pattern & Decorator Pattern (0) | 2021.12.28 |
Comments