2013-08-16 10 views
3

에서 그루비 클래스를 프록시. 예,이 그루비 클래스를 고려하십시오검사 CGLIB 내가 그루비는 반환 및 매개 변수 유형이 방법에 대해 무엇을 배우고, 자바에서 그루비 클래스를 프록시 일부 CGLIB의 메소드를 생성 검사하기 위해 노력하고있어 자바

class Person { 
    String name 
} 

그루비의 이름 속성에 대한 getName()setName() 방법을 생성합니다. getName()은 아마도 String을 반환하고 setName()은 아마도 String을 취합니다.

그러나 CGLIB를 통해이 클래스를 프록시와 CGLIB의 MethodInterceptor, method.getName() 반환 getMetaClassmethod.getReturnType() 반환 groovy.lang.MetaClass를 사용하여 getName에 대한 호출을 차단합니다.

실제 메소드 이름을 배우고 MethodInterceptor 내부에서 형식을 반환하는 방법이 있나요?

편집 : A와 속성을 요청할 때

ExplicitMappingInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 42  
GroovyMMTester$A$$EnhancerByCGLIB$$915b5b4.getMetaClass() line: not available 
CallSiteArray.createPogoSite(CallSite, Object, Object[]) line: 144 
CallSiteArray.createCallSite(CallSite, Object, Object[]) line: 161 
CallSiteArray.defaultCall(CallSite, Object, Object[]) line: 45 
AbstractCallSite.call(Object, Object[]) line: 108 
AbstractCallSite.call(Object) line: 112 
GroovyMMTester$Map.configure() line: 18 <-- Person.getName() call is in here, but doesn't show 
+0

무슨 이유 CGLIB를 사용하지 [메타 클래스 (http://groovy.codehaus.org/Evaluating+the+MetaClass+runtime)? – ChrLipp

+0

당신이 호출하는 것은 Person 객체의 getName()이며 직접 Person.getName()이 아닙니다. 권리? – Alfergon

답변

1

나는 당신이 가지고있는 문제는 직접 메소드를 호출과 함께 할 방법을 호출하는 자바 생각을 가지고 기본적으로 생각합니다. 물론 Java는 그렇게하지는 않지만, JVM에서는 숨겨져 있습니다. Groovy는 JVM을 수정하지 않아 최종 메소드가 호출되기 전에 일련의 메소드가 호출 될 수 있습니다. 이것은 구현 세부 사항이므로 순서가 다를 수 있습니다. Groovy는 런타임 메타 프로그래밍을 사용하는 언어이기 때문에 예상되는 대상 메소드는 전혀 호출되지 않을 수도 있습니다.

어쨌든, 그루비의 방법 대한 getName()를 호출 할 수 있도록, 그루비 런타임은 첫 번째() getMetaClass에 대한 호출 결과 통화가에 만들어지는 개체의 메타 클래스를 얻을 수있다. 여기를 가로 채면 원하는 메쏘드 호출에 도달하지 못할 수도 있습니다.

솔루션

방금 ​​그 헬퍼 메소드를 필터링 ... 사실은 간단합니다. 이것은 $로 시작하는 모든 메소드와이 $로 시작하는 모든 메소드 및 super $ W getMetaClass 메소드입니다. 필터링이란 요격하지 않고 리플렉션을 사용하여 통화를 계속하는 것입니다. 그 세트에없는 한 가지 방법을 만난다면, 아마 그 목표를 가지고있을 것입니다. 귀하의 예에서 method.getName()은 "getName"을 반환합니다.

+0

잘 작동합니다. 감사! – Jonathan

0

이/체크 당신이뿐만 때로는 getName() 메소드를 호출에 사용하는 코드를 공유하십시오 : 여기 Person.getName()의 호출을 차단 호출 스택이다 그루비 객체는이 getProperty 또는 getAttribute 방법을 사용하고, 둘은 실제로 당신에게 무슨 일이 일어나고 있는지 생각합니다 getStaticMetaClass() 메소드를 호출합니다.

는 내 말 대신 Person 객체 O를 직접 getName 호출하는 실제로 getStaticMetaClass().getProperty(..., personObject, 'name', ...)를 호출하는 방법 getProperty(..., personObject, 'name', ...)을 callling 점이다.

예를 들어 method.getName()이라고하는 줄에 중단 점을 넣고 코드를 디버그하고 스택 트레이스에서 getName() 메서드를 호출하는 방법을 살펴볼 수도 있습니다.

+0

OP는 Java에서 리플렉션을 사용하여 반환 유형을 알고 싶어합니다.:) – dmahapatro

+0

CGLib을 사용하여 클래스를 프록시하고 CGLib의 [MethodInterceptor] (http://cglib.sourceforge.net/apidocs/net/sf/cglib/proxy/MethodInterceptor.html)를 사용하여 getName/setName에 대한 호출을 차단합니다. . 이것은 "속성 유형"을 배우고 싶습니다. 불행히도, 인터셉터에서 메소드의 이름이 무엇인지 알지 못하는 것 같아서'method.getName()'은'$ getStaticMetaClass'를 리턴합니다. – Jonathan

+0

코드의 호출 부분을 추가 할 수 있습니까? – Alfergon