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
- pointcut
- 스프링 핵심 기능
- 그리디
- Android
- springdatajpa
- Exception
- db
- java
- SpringBoot
- JDBC
- 인프런
- Spring Boot
- 스프링 핵심 원리
- kotlin
- 백준
- jpa
- 알고리즘
- Proxy
- 자바
- 김영한
- AOP
- QueryDSL
- 스프링
- http
- JPQL
- Servlet
- transaction
- Greedy
- Thymeleaf
- spring
Archives
- Today
- Total
개발자되기 프로젝트
[동적프록시] JDK 동적프록시 - 적용2, 필터 본문
특정 조건을 만족할 때 만 프록시가 동작하도록 하자.
1. LogTraceFilterHandler
public class LogTraceFilterHandler implements InvocationHandler {
private final Object target;
private final LogTrace logTrace;
private final String[] patterns;
public LogTraceFilterHandler(Object target, LogTrace logTrace, String[] patterns) {
this.target = target;
this.logTrace = logTrace;
this.patterns = patterns;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//메서드 이름 필터
String methodName = method.getName();
//save 등등등
if (!PatternMatchUtils.simpleMatch(patterns, methodName)){
return method.invoke(target, args);
}
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;
}
}
}
- LogTraceFilterHandler 는 기존 기능에 다음 기능이 추가되었다.
- 특정 메서드 이름이 매칭 되는 경우에만 LogTrace 로직을 실행한다.
- 이름이 매칭되지 않으면 실제 로직을 바로 호출한다.
- 스프링이 제공하는 PatternMatchUtils.simpleMatch(..) 를 사용하면 매칭 로직을 쉽게 적용할 수 있다.
- xxx : xxx가 정확히 매칭되면 참
- xxx* : xxx로 시작하면 참
- *xxx : xxx로 끝나면 참
- *xxx* : xxx가 있으면 참
- String[] patterns : 적용할 패턴은 생성자를 통해서 외부에서 받음.
2. Bean 등록
@Configuration
public class DynamicProxyFilterConfig {
private static final String[] PATTERNS = {"request*", "order*", "save*"};
@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 LogTraceFilterHandler(orderController, logTrace, PATTERNS));
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 LogTraceFilterHandler(orderService, logTrace, PATTERNS));
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 LogTraceFilterHandler(orderRepository, logTrace, PATTERNS));
return proxy;
}
}
- public static final String[] PATTERNS = {"request*", "order*", "save*"}; 적용할 패턴이다.
- request , order , save 로 시작하는 메서드에 로그가 남는다.
- LogTraceFilterHandler : 앞서 만든 필터 기능이 있는 핸들러를 사용한다.
- 그리고 핸들러에 적용 패턴도 넣어줌.
3. 실행
@Import(DynamicProxyFilterConfig.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();
}
}
noLog()를 호출하는 경우 로그가 남지 않는다!
4. JDK 동적 프록시의 한계
- JDK 동적 프록시는 인터페이스가 필수이다.
- 그렇다면 V2 애플리케이션 처럼 인터페이스 없이 클래스만 있는 경우에는????
- 어떻게 동적 프록시를 적용??
- CGLIB 라는 바이트코드를 조작하는 특별한 라이브러리를 사용해야한다.
5. GitHiub : 211230 JDK Dynamic Proxy 3
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
[프록시 팩토리] 스프링이 지원하는 프록시 (0) | 2021.12.30 |
---|---|
[동적 프록시] CGLIB - 구체클래스 기반 (0) | 2021.12.30 |
[동적프록시] JDK 동적프록시 - 적용 (0) | 2021.12.30 |
[동적프록시] JDK 동적프록시 - 소개 (0) | 2021.12.30 |
[동적프록시] 리플렉션 (0) | 2021.12.30 |
Comments