Prefacio : Quiero crear un proxy de un proxy existido (utilizando el paquete de cglib en primavera), al igual que cuando llamo a la clase de método original ambos métodos de ambos poderes llamados en primer lugar. ¿Tiene algún sentido? o ¿es posible?
Problema: Cuando estoy creando el segundo enhancer
, tengo la java.lang.ClassFormatError-->Duplicate method name "newInstance" with signature "
excepción.
Código de ejemplo es como sigue
Clase inicial
public class OriginalClass {
public void print(){
System.out.println("MAIN METHOD");
}
}
Crear dos servidores proxy
public class Main {
public static void main(String[] args) {
//Create First Proxy
Enhancer firstEnhancer= new Enhancer();
firstEnhancer.setSuperclass(OriginalClass.class);
firstEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT FIRST PROXY");
return methodProxy.invokeSuper(o, objects);
});
OriginalClass firstProxy = (OriginalClass) firstEnhancer.create();
//Create Second Proxy
Enhancer secondEnhancer= new Enhancer();
secondEnhancer.setSuperclass(firstProxy.getClass());
secondEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT SECOND PROXY");
return methodProxy.invokeSuper(o, objects);
});
//Getting Exception on this line
OriginalClass secondProxy = (OriginalClass) secondEnhancer.create();
//Call
secondProxy.print();
}
}
El resultado esperado es el siguiente (impresión)
METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD
Pero me da el siguiente excepción (al crear el segundo apoderado)
Caused by: java.lang.ClassFormatError: Duplicate method name "newInstance" with signature "([Lorg.springframework.cglib.proxy.Callback;)Ljava.lang.Object;" in class file com/test/OriginalClass$$EnhancerByCGLIB$$37b306ed$$EnhancerByCGLIB$$15133919
Escenario Mundo Real
Quiero envolver un proxy en todos los granos que han sido delegados por la primavera, usando BeanPostProcessors
y cglib
. Por ejemplo, quiero envolver un proxy en todos los @transactional
métodos (log antes y después de las transacciones).
Actualización : Yo prefiero crear proxies , no POAs (AOP es en sí mismo un proxy).
He encontrado soultion de trabajo, funciona cuando se utiliza methodProxy.invoke()
en lugar de methodProxy.invokeSuper()
en el segundo potenciador, también la firstProxy
necesidad de pasar a la invocación en lugar del o
objeto y la superclase se establece en el original, que no tiene el método newInstance:
public class Test {
public static void main(String[] args) {
//Create First Proxy
Enhancer firstEnhancer= new Enhancer();
firstEnhancer.setSuperclass(OriginalClass.class);
firstEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT FIRST PROXY");
return methodProxy.invokeSuper(o, objects);
});
OriginalClass firstProxy = (OriginalClass) firstEnhancer.create();
//Create Second Proxy
Enhancer secondEnhancer= new Enhancer();
secondEnhancer.setSuperclass(firstProxy.getClass().getSuperclass());
// secondEnhancer.setSuperclass(OriginalClass.class);
secondEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT SECOND PROXY");
return methodProxy.invoke(firstProxy, objects);
});
//Getting Exception on this line
OriginalClass secondProxy = (OriginalClass) secondEnhancer.create();
//Call
secondProxy.print();
}
}
resultado:
METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD