前言:我想创建一个现有代理的代理(在Spring使用cglib包),就像当我调用原始方法类时,两个代理的两个方法都首先被调用一样。有什么意义吗?还是有可能?
问题:创建第二个时enhancer,出现 java.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
现实世界场景 我想包装上已经由Spring代理,利用一切豆类代理BeanPostProcessors和cglib。例如,我想在所有@transactional方法上包装一个代理(在事务之前和之后记录日志)。
更新:我更喜欢创建代理而不是AOP。(AOP本身是代理)
问题来源:Stack Overflow
我已经找到了可行的方案,它可以在第二个增强器中使用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
回答来源:Stack Overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。