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
- QueryDSL
- kotlin
- Servlet
- Proxy
- 자바
- spring
- 스프링
- java
- Exception
- Android
- transaction
- AOP
- 김영한
- db
- jpa
- 인프런
- Greedy
- pointcut
- Thymeleaf
- 백준
- http
- 스프링 핵심 원리
- 알고리즘
- JPQL
- Spring Boot
- SpringBoot
- JDBC
- 스프링 핵심 기능
- springdatajpa
- 그리디
Archives
- Today
- Total
개발자되기 프로젝트
[동적프록시] JDK 동적프록시 - 적용 본문
JDK 동적프록시는 인터페이스가 필수이다. 따라서 V1에 적용해보자.
1. LogTraceBasicHandler
import hello.proxy.trace.TraceStatus;
import hello.proxy.trace.logtrace.LogTrace;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogTraceBasicHandler implements InvocationHandler {
private final Object target;
private final LogTrace logTrace;
public LogTraceBasicHandler(Object target, LogTrace logTrace) {
this.target = target;
this.logTrace = logTrace;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
TraceStatus status = null;
try{
String message = method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()";
status = logTrace.begin(message);
//로직 호출
Object result = method.invoke(target, args);
logTrace.end(status);
return result;
}catch (Exception e){
logTrace.exception(status, e);
throw e;
}
}
}
- LogTraceBasicHandler 는 InvocationHandler 인터페이스를 구현해서 JDK 동적 프록시에서
사용된다. - private final Object target : 프록시가 호출할 대상이다.
- String message = method.getDeclaringClass().getSimpleName() + "." ...
- LogTrace 에 사용할 메시지이다. 프록시를 직접 개발할 때는 "OrderController.request()" 와 같이
프록시마다 호출되는 클래스와 메서드 이름을 직접 남겼다.
이제는 Method 를 통해서 호출되는 메서드 정보와 클래스 정보를 동적으로 확인할 수 있기 때문에
이 정보를 사용하면 된다.
- LogTrace 에 사용할 메시지이다. 프록시를 직접 개발할 때는 "OrderController.request()" 와 같이
- 동적 프록시를 사용하도록 수동 빈 등록을 설정하자
2. Bean 등록
@Configuration
public class DynamicProxyBasicConfig {
@Bean
public OrderControllerV1 orderControllerV1(LogTrace logTrace){
OrderControllerV1 orderController = new OrderControllerV1Impl(orderServiceV1(logTrace));
OrderControllerV1 proxy = (OrderControllerV1) Proxy.newProxyInstance(OrderControllerV1.class.getClassLoader(),
new Class[]{OrderControllerV1.class},
new LogTraceBasicHandler(orderController, logTrace));
return proxy;
}
@Bean
public OrderServiceV1 orderServiceV1(LogTrace logTrace){
OrderServiceV1 orderService = new OrderServiceV1Impl(orderRepositoryV1(logTrace));
OrderServiceV1 proxy = (OrderServiceV1) Proxy.newProxyInstance(OrderServiceV1.class.getClassLoader(),
new Class[]{OrderServiceV1.class},
new LogTraceBasicHandler(orderService, logTrace));
return proxy;
}
@Bean
public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace){
OrderRepositoryV1 orderRepository = new OrderRepositoryV1Impl();
OrderRepositoryV1 proxy = (OrderRepositoryV1) Proxy.newProxyInstance(OrderRepositoryV1.class.getClassLoader(),
new Class[]{OrderRepositoryV1.class},
new LogTraceBasicHandler(orderRepository, logTrace));
return proxy;
}
}
- 이전에는 프록시 클래스를 직접 개발했지만,
- 이제는 JDK 동적 프록시 기술을 사용해서 각각의 Controller , Service , Repository 에 맞는 동적 프록시 생성
- LogTraceBasicHandler : 동적 프록시를 만들더라도 LogTrace 를 출력하는 로직은 모두 같기 때문에
프록시는 모두 LogTraceBasicHandler 를 사용한다.
3. 실행, 결과
@Import(DynamicProxyBasicConfig.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();
}
}
[4f7429ae] OrderControllerV1.request()
[4f7429ae] |-->OrderServiceV1.orderItem()
[4f7429ae] | |-->OrderRepositoryV1.save()
[4f7429ae] | |<--OrderRepositoryV1.save() time=1000ms
[4f7429ae] |<--OrderServiceV1.orderItem() time=1001ms
[4f7429ae] OrderControllerV1.request() time=1002ms
4. 의존관계
하지만 no-log를 실행해도 동적 프록시가 적용되고, LogTraceBasicHandler 가 실행되기 때문에 로그가 남는다.
이 부분을 로그가 남지 않도록 처리해야 한다.
5. GitHub : 211230 JDK Dynamic Proxy 2
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
[동적 프록시] CGLIB - 구체클래스 기반 (0) | 2021.12.30 |
---|---|
[동적프록시] JDK 동적프록시 - 적용2, 필터 (0) | 2021.12.30 |
[동적프록시] JDK 동적프록시 - 소개 (0) | 2021.12.30 |
[동적프록시] 리플렉션 (0) | 2021.12.30 |
인터페이스기반 프록시와 클래스 기반 프록시 (0) | 2021.12.30 |
Comments