spring中使用cglib的嵌套代理



前言:我想创建一个现有代理的代理(在spring中使用cglib包(,就像我调用原始方法类时,首先调用两个代理的两个方法。这有意义吗?还是有可能?

问题:当我创建第二个enhancerjava.lang.ClassFormatError-->Duplicate method name "newInstance" with signature "异常。


示例代码如下

原始类别

public class OriginalClass {
public void print(){
System.out.println("MAIN METHOD");
}
}

创建两个代理

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();
}
}

预期结果如下(打印(

METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD

但我得到了以下异常(在创建第二个代理时(

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

真实世界场景

我想使用BeanPostProcessorscglib在spring代理的所有bean上封装一个代理。例如,我想在所有@transactional方法上包装一个代理(在事务之前和之后记录(。

更新:我更喜欢创建代理,而不是AOP。(AOP本身就是一个代理(

我发现了工作灵魂,当在第二个增强器中使用methodProxy.invoke()而不是methodProxy.invokeSuper()时,它就可以工作,而且firstProxy需要传递给调用,而不是o对象,并且superClass被设置为原始的,它没有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();
}
}

结果:

METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD

最新更新