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
- jpa
- 김영한
- 인프런
- spring
- transaction
- 스프링
- kotlin
- AOP
- db
- Exception
- Greedy
- SpringBoot
- 백준
- java
- springdatajpa
- 스프링 핵심 원리
- QueryDSL
- pointcut
- Thymeleaf
- 그리디
- 자바
- Servlet
- Proxy
- Android
- 스프링 핵심 기능
- JDBC
- Spring Boot
- http
- JPQL
- 알고리즘
Archives
- Today
- Total
개발자되기 프로젝트
프록시 팩토리 - 적용1 본문
지금까지 학습한 프록시 팩토리를 사용해서 애플리케이션에 프록시를 만들어보자.
먼저 인터페이스가 있는 v1 애플리케이션에 LogTrace 기능을 프록시 팩토리를 통해서 프록시를 만들어
적용해보자.
1. Advice
public class LogTraceAdvice implements MethodInterceptor {
private final LogTrace logTrace;
public LogTraceAdvice(LogTrace logTrace) {
this.logTrace = logTrace;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
TraceStatus status = null;
try{
Method method = invocation.getMethod();
String message = method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()";
status = logTrace.begin(message);
//로직 호출
Object result = invocation.proceed();
logTrace.end(status);
return result;
}catch (Exception e){
logTrace.exception(status, e);
throw e;
}
}
}
2. Config
@Slf4j
@Configuration
public class ProxyFactoryConfigV1 {
@Bean
public OrderControllerV1 orderControllerV1(LogTrace logTrace){
OrderControllerV1 orderController = new OrderControllerV1Impl(orderServiceV1(logTrace));
ProxyFactory proxyFactory = new ProxyFactory(orderController);
proxyFactory.addAdvisor(getAdvisor(logTrace));
OrderControllerV1 proxy = (OrderControllerV1) proxyFactory.getProxy();
log.info("Proxyfactory proxy={}, target={}", proxy.getClass(), orderController.getClass());
return proxy;
}
@Bean
public OrderServiceV1 orderServiceV1(LogTrace logTrace){
OrderServiceV1 orderService = new OrderServiceV1Impl(orderRepositoryV1(logTrace));
ProxyFactory proxyFactory = new ProxyFactory(orderService);
proxyFactory.addAdvisor(getAdvisor(logTrace));
OrderServiceV1 proxy = (OrderServiceV1) proxyFactory.getProxy();
log.info("Proxyfactory proxy={}, target={}", proxy.getClass(), orderService.getClass());
return proxy;
}
@Bean
public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace){
OrderRepositoryV1Impl orderRepository = new OrderRepositoryV1Impl();
ProxyFactory proxyFactory = new ProxyFactory(orderRepository);
proxyFactory.addAdvisor(getAdvisor(logTrace));
OrderRepositoryV1 proxy = (OrderRepositoryV1) proxyFactory.getProxy();
log.info("Proxyfactory proxy={}, target={}", proxy.getClass(), orderRepository.getClass());
return proxy;
}
private Advisor getAdvisor(LogTrace logTrace) {
//point cut
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.setMappedNames("request*", "order*", "save*");
//advice
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice);
}
}
- 포인트컷은 NameMatchMethodPointcut 을 사용한다.
- 여기에는 심플 매칭 기능이 있어서 * 을 매칭할 수 있다.
- request* , order* , save* : request 로 시작하는 메서드에 포인트컷은 true 를 반환한다.
- 나머지도 같다.
- 이렇게 설정한 이유는 noLog() 메서드에는 어드바이스를 적용하지 않기 위해서다.
- 어드바이저는 포인트컷( NameMatchMethodPointcut ), 어드바이스( LogTraceAdvice )를 가지고 있다.
- 프록시 팩토리에 각각의 target 과 advisor 를 등록해서 프록시를 생성한다. 그리고 생성된 프록시를
스프링 빈으로 등록한다.
3. 실행
@Import(ProxyFactoryConfigV1.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();
}
}
Proxyfactory proxy=class com.sun.proxy.$Proxy50, target=class hello.proxy.app.v1.OrderRepositoryV1Impl
Proxyfactory proxy=class com.sun.proxy.$Proxy52, target=class hello.proxy.app.v1.OrderServiceV1Impl
Proxyfactory proxy=class com.sun.proxy.$Proxy53, target=class hello.proxy.app.v1.OrderControllerV1Impl
Tomcat started on port(s): 8080 (http) with context path ''
(JVM running for 4.941)
Initializing Spring DispatcherServlet 'dispatcherServlet'
Initializing Servlet 'dispatcherServlet'
Completed initialization in 1 ms
[7e3d056c] OrderControllerV1.request()
[7e3d056c] |-->OrderServiceV1.orderItem()
[7e3d056c] | |-->OrderRepositoryV1.save()
[7e3d056c] | |<--OrderRepositoryV1.save() time=1010ms
[7e3d056c] |<--OrderServiceV1.orderItem() time=1012ms
[7e3d056c] OrderControllerV1.request() time=1013ms
- V1 애플리케이션은 인터페이스가 있기 때문에 프록시 팩토리가 JDK 동적 프록시를 적용한다.
- 애플리케이션 로딩 로그를 통해서 JDK 동적 프록시가 적용된 것을 확인할 수 있다.->com.sun.proxy.$Proxy50,
4. GitHub : 220101 ProxyFactory 1
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
프록시팩토리- 정리 (0) | 2022.01.01 |
---|---|
프록시팩토리 - 적용 2 (0) | 2022.01.01 |
여러 개의 Advisor 적용 (0) | 2022.01.01 |
Pointcut - 스프링이 제공하는 pointcut (0) | 2021.12.31 |
Advisor - 예제, PointCut 만들기 (0) | 2021.12.31 |
Comments