| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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
- Spring ipfs
- kotiln functional interface
- java 1238
- spring mongodb
- java 백준 1509
- java 팩토리얼 개수
- javav 1676
- spring mongoTemplate switch
- kotiln const
- 익명 객체 @transactional
- spring mongodb switch
- 자바 백준 팩토리얼 개수
- ipfs singletone
- 자바 1676
- go
- rabbitmq 싱글톤
- 백준 연결요소 자바
- spring mongoTemplate
- Claude Intelij 연결
- mongodb lookup
- nodejs rabbitmq
- 백준 1504 java
- java 1509
- kotiln const val
- 백준 2252 줄세우기
- 백준 특정한 최단 경로
- ipfs bean
- java 파티
- Java Call By Refernce
- 안정해시
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 |