当前位置: 首页 > 知识库问答 >
问题:

spring中使用cglib的嵌套代理

穆劲
2023-03-14

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

问题:当我创建第二个增强器时,我得到java.lang.ClassFormatError-->具有签名“异常的重复方法名”newInstance“。

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本身就是一个代理)

共有1个答案

董谦
2023-03-14

我找到了一个有效的方法,它在第二个增强器中使用methodProxy.invoke()而不是methodProxy.invokeSuper()时起作用,而且firstproxy需要传递给调用,而不是O对象,并且超类被设置为原来的那个超类,那个超类没有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
 类似资料:
  • 我在读一些关于Spring AOP的文章,遇到了这样的情况: AOP代理:由AOP创建的对象,用于实现方面契约。在Spring中,代理对象可以是JDK动态代理或CGLIB代理。默认情况下,代理对象将是JDK动态代理,被代理的对象必须实现一个接口,该接口也将由代理对象实现。但是像CGLIB这样的库也可以通过子类创建代理,因此不需要接口。 您能否看看下面的结构,并想象一下我们想要建议方法。

  • 我正在寻找HAL中嵌套_embedded如何使用Spring HATEOAS API编程的例子。最佳实践是什么? 下面是我想要实现的一个例子:

  • 我想在SpringBoot中使用quartz运行一个作业,其中多个线程将执行该方法。我想要的是将每次处理的结果都保存在redis中,这样我就可以知道这个工作有多好。 我想以这种形式保存redis中的数据。 我想插入关键日期中的所有项目。因为有多个线程在工作,所以每个线程都在处理某个项目。所以所有项目都应该只插入到键(日期)中。 可能吗? 一种解决方案是一次又一次地重写(date)键的数据,首先从r

  • 本文向大家介绍spring cglib 与 jdk 动态代理,包括了spring cglib 与 jdk 动态代理的使用技巧和注意事项,需要的朋友参考一下 1. 概述 JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理 Cglib动态代理是 利用asm开源包 把被代理类的class文件加载进来 通过修改其字节码生成子类来处

  • 问题内容: 使用vlcj组件,由于AOP代理对象为null,因此自定义组件出现。 MediaList类别 自定义MediaList类 弹簧配置类 AOP配置类 测试代码 我尝试单步跟踪,当TestMediaList构建完成时。该方法的MediaListInstance()返回正常值,但是当spring返回到代理对象时,将返回null。同时,如果您不使用AOP,我也会尝试正确返回该值。因此,我确定了

  • 我有混合堆栈:EJB和Spring。为了将Spring自动连接到EJB,我使用(不确定这是否会影响我遇到的问题)。 Whlie试图通过以下方式自动连接bean: 我得到错误: 据我所知,问题是使用了JDK代理(因为实现了接口),而我需要cglib代理。 不确定是否相关,但我运行的是glassfish 3.1.x。 和stacktrace(部分,因为我不能在这里公开所有类名: