일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- java 1238
- 백준 1504 java
- Java Call By Refernce
- kotiln functional interface
- 자바 백준 팩토리얼 개수
- 백준 연결요소 자바
- spring mongoTemplate switch
- 백준 2252 줄세우기
- java 파티
- rabbitmq 싱글톤
- 전략 패턴이란
- java 1509
- 안정해시
- ipfs bean
- java 백준 1509
- javav 1676
- 자바 1676
- mongodb lookup
- kotiln const val
- spring mongodb switch
- spring mongodb
- 익명 객체 @transactional
- go
- 백준 특정한 최단 경로
- ipfs singletone
- Spring ipfs
- kotiln const
- java 팩토리얼 개수
- spring mongoTemplate
- nodejs rabbitmq
Archives
- Today
- Total
공부 흔적남기기
jdk dynamic proxy | cglib 본문
728x90
반응형
jdk dynamic proxy와 cglib
둘은 어디에 쓰이는 걸까? 이름에서 볼 수 있다시피 proxy를 동적으로 만들어주는 라이브러리다.
jdk dynamic proxy는 java의 reflection을 이용해서 프록시를 만들고
cglib는 바이트코드 수준에서 코드를 조작하여 프록시를 생성한다.
jdk dynamic proxy는 어떻게 사용할까
jdk dynamic proxy는 java의 invocationHandler interface를 구현해서 사용한다.
proxy의 target은 interface만 들어갈 수 있다.
예시
class LogInvocationHandler(
private val target : Any,
private val logService: LogServiceDirtyCode
) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any?>?): Any {
val className = method?.declaringClass?.name ?: ""
val methodName = method?.name ?: ""
var trace: Trace? = null
return runCatching {
trace = logService.begin(className + methodName)
val methodArgs = args ?: emptyArray()
method?.invoke(target, *methodArgs) ?: throw IllegalArgumentException("mehtod null")
}.onSuccess {
logService.finish(trace!!)
}.onFailure {
logService.execption(trace!!, it)
throw it
}.getOrThrow()
}
}
생성한 invocation을 Proxy.newInstance를 이용해서 사용할 수 있다.
fun itemControllerJdkProxy(logService: LogServiceDirtyCode): ItemControllerJdkProxy {
return Proxy.newProxyInstance(
ItemControllerJdkProxy::class.java.classLoader,
arrayOf(ItemControllerJdkProxy::class.java),
LogInvocationHandler(ItemControllerJdkProxyImpl(itemServiceJdkProxy(logService)), logService)
) as ItemControllerJdkProxy
}
cglib는 어떻게 사용할까?
cglib는 code generator library의 약자이다 (참고)
cglib는 spring proxy의 MethodInterceptor interface를 구현해 사용한다.
target으로 구현 객체만 들어올 수 있다.(최근에는 인터페이스도 들어 올 수 있게 바꾼 것 같다.)
예시
class LogMethodInterceptor(
private val logService: LogServiceDirtyCode,
private val target: Any
): MethodInterceptor {
override fun intercept(obj: Any?, method: Method?, args: Array<out Any>?, methodProxy: MethodProxy?): Any {
val className = method?.declaringClass?.name ?: ""
val methodName = method?.name ?: ""
if(methodName.contains("toString")){
return target.toString();
}
var trace: Trace? = null
return runCatching {
trace = logService.begin(className + methodName)
val methodArgs = args ?: emptyArray()
methodProxy?.invoke(target, methodArgs) ?: throw IllegalArgumentException("mehtod null")
}.onSuccess {
logService.finish(trace!!)
}.onFailure {
logService.execption(trace!!, it)
throw it
}.getOrThrow()
}
}
이는 Enhacer.create를 통해 proxy 를 만들어 사용할 수있다.
fun itemRepositoryProxy(logService: LogServiceDirtyCode): ItemRepositoryRealSubject {
return Enhancer.create(
ItemRepositoryRealSubject::class.java,
LogMethodInterceptor(logService, ItemRepositoryRealSubject())
) as ItemRepositoryRealSubject
}
728x90
반응형
'web study > 배경지식' 카테고리의 다른 글
언제 관계형 데이터베이스 이외의 것을 사용해야 할까? (0) | 2025.03.13 |
---|---|
프록시 패턴 | 데코레이터 패턴 (0) | 2023.12.18 |
전략 패턴이란 (0) | 2023.05.24 |
템플릿 메서드 패턴이란 (0) | 2023.05.22 |
Sentry 적용시 기본 설정 (0) | 2023.04.14 |