Proxy
์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์

์ฌ๊ธฐ์ ๋ก๊ทธ ์ถ์ ์ฉ ํ๋ก์๋ฅผ ์ถ์ ํ๋ฉด ์ด๋ ๊ฒ ๋๋ค.


๊ฐ๊ฐ ์ธํฐํ์ด์ค์ ๋ง๋ ํ๋ก์ ๊ตฌํ์ฒด๋ฅผ ์ถ๊ฐํ ๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์์ ์ ํ๋ก์๋ฅผ ์ฌ์ฉํ๋๋ก ์์กด ๊ด๊ณ๋ฅผ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
@RequiredArgsConstructor
public class OrderRepositoryInterfaceProxy implements OrderRepositoryV1 {
private final OrderRepositoryV1 target;//์ค์ ๊ฐ์ฒด
private final LogTrace logTrace;
@Override
public void save(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderRepository.save()");
target.save(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
@RequiredArgsConstructor
public class OrderServiceInterfaceProxy implements OrderServiceV1 {
private final OrderServiceV1 target;//์ค์ ๊ฐ์ฒด
private final LogTrace logTrace;
@Override
public void orderItem(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderService.orderItem()");
target.orderItem(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
@RequiredArgsConstructor
public class OrderControllerInterfaceProxy implements OrderControllerV1 {
private final OrderControllerV1 target;//์ค์ ๊ฐ์ฒด
private final LogTrace logTrace;
@Override
public String request(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderController.request()");
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();
}
}@Configuration
public class InterfaceProxyConfig {
@Bean
public OrderControllerV1 orderController(LogTrace logTrace) {
OrderControllerV1Impl controllerImpl = new OrderControllerV1Impl(orderService(logTrace));
return new OrderControllerInterfaceProxy(controllerImpl, logTrace);//ํ๋ก์ ๋น ๋ฑ๋ก
}
@Bean
public OrderServiceV1 orderService(LogTrace logTrace) {
OrderServiceV1Impl serviceImpl = new OrderServiceV1Impl(orderRepository(logTrace));
return new OrderServiceInterfaceProxy(serviceImpl, logTrace);//ํ๋ก์ ๋น ๋ฑ๋ก
}
@Bean
public OrderRepositoryV1 orderRepository(LogTrace logTrace) {
OrderRepositoryV1Impl repositoryImpl = new OrderRepositoryV1Impl();
return new OrderRepositoryInterfaceProxy(repositoryImpl, logTrace);//ํ๋ก์ ๋น ๋ฑ๋ก
}
}
@Import(InterfaceProxyConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app.v3")
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Bean
public LogTrace logTrace() {
return new ThreadLocalLogTrace();
}
}์ค์ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ์ง ์๊ณ ํ๋ก์๋ฅผ ์ค์ ์คํ๋ง ๋น ๋์ ๋ฑ๋กํ๋ค.
ํ๋ก์๋ ๋ด๋ถ์ ์ค์ ๊ฐ์ฒด(ํ๊ฒ)๋ฅผ ์ฐธ์กฐํ๊ณ ์๋ค.


์คํ๋ง ์ปจํ ์ด๋๋ ์ค์ ๊ฐ์ฒด๊ฐ ์๋๋ผ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๊ณ ๊ด๋ฆฌํ๋ค.
์ค์ ๊ฐ์ฒด๋ ์คํ๋ง ์ปจํ ์ด๋์๋ ์๊ด์ด ์๊ณ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํตํด์ ์ฐธ์กฐ๋ ๋ฟ์ด๋ค.
๊ตฌ์ฒด ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์
@RequiredArgsConstructor
public class OrderRepositoryConcreteProxy extends OrderRepositoryV2 {
private final OrderRepositoryV2 target;
private final LogTrace logTrace;
@Override
public void save(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderRepository.save()");
target.save(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
public class OrderServiceConcreteProxy extends OrderServiceV2 {
private final OrderServiceV2 target;
private final LogTrace logTrace;
public OrderServiceConcreteProxy(OrderServiceV2 target, LogTrace logTrace) {
super(null);//๋ถ๋ชจ์ ์์ฑ์๋ฅผ ํธ์ถํด์ผ ํจ.
this.target = target;
this.logTrace = logTrace;
}
@Override
public void orderItem(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin("OrderService.orderItem()");
target.orderItem(itemId);
logTrace.end(status);
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
public class OrderControllerConcreteProxy extends OrderControllerV2 {
private final OrderControllerV2 target;
private 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("OrderController.request()");
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();
}
}@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);
}
}
@Import(ConcreteProxyConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app.v3")
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Bean
public LogTrace logTrace() {
return new ThreadLocalLogTrace();
}
}์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์์ ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์
์ธํฐํ์ด์ค๊ฐ ์์ด๋ ํด๋์ค ๊ธฐ๋ฐ์ผ๋ก ํ๋ก์๋ฅผ ์์ฑํ ์ ์๋ค.
ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์๋ ์์์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ๋จ์ ์ด ์๋ค.
๋ถ๋ชจ ํด๋์ค์ ์์ฑ์๋ฅผ ํธ์ถํด์ผ ํ๋ค.
ํด๋์ค์
finalํค์๋๊ฐ ๋ถ์ผ๋ฉด ์์์ด ๋ถ๊ฐ๋ฅํ๋ค.๋ฉ์๋์
finalํค์๋๊ฐ ๋ถ์ผ๋ฉด ์ค๋ฒ๋ผ์ด๋์ ํ ์ ์๋ค.
๋์ฒด์ ์ผ๋ก ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์๋ณด๋ค๋ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ์ ํ๋ก์๊ฐ ๋ ์ข๋ค. ์ธํฐํ์ด์ค ๊ธฐ๋ฐ์ ํ๋ก์๋ ์์์ด๋ผ๋ ์ ์ฝ์์ ์์ ๋กญ๋ค.
์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์์ ๋จ์ ์ ์ธํฐํ์ด์ค๊ฐ ํ์ํ๋ค๋ ๊ฒ์ด๋ค. ์ธํฐํ์ด์ค๊ฐ ์๋ค๋ฉด ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ๋ง๋ค ์ ์๋ค.
์ด๋ก ์ ์ผ๋ก๋ ๋ชจ๋ ๊ฐ์ฒด์ ์ธํฐํ์ด์ค๋ฅผ ๋์ ํด์ ์ญํ ๊ณผ ๊ตฌํ์ ๋๋๋ ๊ฒ์ด ์ข๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ญํ ๊ณผ ๊ตฌํ์ ๋๋์ด์ ๊ตฌํ์ฒด๋ฅผ ํธ๋ฆฌํ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค.
์ธํฐํ์ด์ค๋ฅผ ๋์ ํ๋ ๊ฒ์ ๊ตฌํ์ ๋ณ๊ฒฝํ ๊ฐ๋ฅ์ฑ์ด ์์ ๋ ํจ๊ณผ์ ์ธ๋ฐ ๊ตฌํ์ ๋ณ๊ฒฝํ ๊ฐ๋ฅ์ฑ์ด ๊ฑฐ์ ์๋ ์ฝ๋์ ์ธํฐํ์ด์ค๋ฅผ ์ ์ฉํ๋ ๊ฒ์ ๋ฒ๊ฑฐ๋กญ๊ณ ์ค์ฉ์ ์ด์ง ์๋ค.
์ด๋ฐ ๊ณณ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ฉํ๊ธฐ ๋ณด๋ค ๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ์๋ ์๋ค.
ํ๋ก์๋ฅผ ์ฌ์ฉํด์ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ก๊ทธ ์ถ์ ๊ธฐ๋ผ๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ ์ ์์๋ค. ๋ฌธ์ ๋ ํ๋ก์ ํด๋์ค๋ฅผ ๋๋ฌด ๋ง์ด ๋ง๋ค์ด์ผ ํ๋ค๋ ์ ์ด๋ค.
ํ๋ก์ ํด๋์ค๊ฐ ํ๋ ๋ก์ง์ ๋์ ํด๋์ค๋ง ๋ค๋ฅผ ๋ฟ ๋ชจ๋ ๋๊ฐ๋ค. ํ๋ก์ ํด๋์ค๋ฅผ ํ๋๋ง ๋ง๋ค์ด์ ๋ชจ๋ ๊ณณ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๊น?
๋์ ํ๋ก์ ๊ธฐ์ ์ด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ค๋ค.
Last updated