`
足至迹留
  • 浏览: 496816 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

内部类引发的cglib创建失败

阅读更多
1. 问题描述
使用cglib库进行动态生成代理类时调用了默认改造方法,enhancer.create(),为了省事,把目标类写成了内部类,导致错误:
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
	at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
	at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
	at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
	at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
	at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
	at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)


源码:
public class CglibTest
{
    @Test
    public void createTest()
    {
        Student1 defaultProxy = (Student1)this.createCglibProxy(Student1.class);

        defaultProxy.print();
    }

    private Object createCglibProxy(Class targetClass)
    {
        // 也可以使用Enhancer的静态create方法,不需要new 实例。但这样能更好的控制实例配置。
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallback(NoOp.INSTANCE);

        return enhancer.create();
    }

    public class Student1
    {
        private int age;
        private String name;

        public int getAge()
        {
            return this.age;
        }

        public String getName()
        {
            return this.name;
        }

        public void print()
        {
            System.out.println("age:" + age + ", name:" + name);
        }
    }
}


2. 问题分析
报错显示创建的时候没有给构造方法参数,明显看上去Student1使用的是默认构造方法,不需要参数啊。为了看究竟,查看Student1的反射方法,构造方法果然有一个参数,类型是CglibTest... 原来是通过构造方法外部类被传入了内部类,这也是为什么内部类可以直接调用外部类的成员了。
详细参考:
http://www.2cto.com/kf/201402/281879.html
要点:
1 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象的引用;
2 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为1中添加的成员变量赋值;
3 在调用内部类的构造函数初始化内部类对象时, 会默认传入外部类的引用。

3. 问题解决
三种方法:
1. 把Student1定义成static 内部类
2. 把Student1拿到外面单独定义
3. cglib创建时传入外部类对象:
enhancer.create(new Class[]{CglibTest.class}, new Object[]{this});
分享到:
评论

相关推荐

    cglib创建代理类.rar

    springAOP等框架中,大量用到代理技术; 两类代理技术: 1,java动态代理,见JDK文档或相关java书;...2.cglib创建代理类,比第一种更加简单,代理类和背代理类不需要实现共同接口。本例子就是cglib代理的例子,很简单

    cglib动态生成java类

    在Java编程中,我们有时需要在运行时动态地创建或修改类,CGLib就是为此目的而设计的。它广泛应用于AOP(面向切面编程)框架,如Spring AOP,以及单元测试工具,如Mockito。 ### CGLib的工作原理 CGLib通过继承目标...

    cglib.jar下载

    通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。...

    cglib及其依赖包

    3. `asm-2.2.3.jar`:ASM的基本库,提供了核心的字节码操作和分析功能,CGLib内部就是依赖这个库来实现对Java字节码的读取、修改和生成。 4. `asm-commons-2.2.3.jar`:ASM的通用库,包含了一些用于处理常见的字节...

    cglib的依赖包

    通过创建目标类的子类,并在子类中拦截并增强方法调用,CGlib可以实现对无接口类的代理。 2. **AOP实现**:在Spring框架中,CGlib是实现AOP的重要组件。它能够生成代理对象,当方法被调用时,先执行切面逻辑,然后...

    cglib_cglib.zip

    当一个类被代理时,CGLib会创建该类的一个子类,并在子类中覆盖方法,以此实现对目标类的拦截和增强。这种方法尤其适用于那些无法通过接口代理(如Java的InvocationHandler)的情况,比如需要代理的类没有实现任何...

    CGLIB依赖jar包

    CGLIB是基于ASM(一个底层的Java字节码操作和分析框架)来实现的,它允许开发者在运行时为Java类创建子类,而无需访问其源代码或重新编译。这种技术在许多场景下都非常有用,比如实现AOP(面向切面编程)中的动态...

    Cglib3.3.0最新版jar包

    8. **注意事项**:尽管Cglib提供了便捷的类生成能力,但生成的子类可能会增加内存占用,且对于final方法或final类,Cglib无法生成子类,这时需要考虑其他代理方案,如Java的动态代理。 总的来说,Cglib3.3.0作为一...

    cglib2.2.jar

    1. **创建代理类**:当需要对一个类进行动态代理时,CGLIB会生成一个新的子类,这个子类继承自原始类,并添加了额外的方法用于拦截和处理方法调用。 2. **方法拦截器**:CGLIB使用`Enhancer`类来创建代理对象,并...

    cglib-nodep

    1. **创建子类**: 当需要代理一个类时,CGlib会动态生成一个新的类,这个新类继承自原始类,并且添加了一个名为`Enhancer`的内部类。这个内部类包含了实际的增强逻辑。 2. **方法拦截**: 通过实现`...

    cglib_cglib3.2_remain3gr_cglibjar包_cglib.jar_

    CGLib的主要功能包括创建动态代理、动态创建子类以及在运行时修改类的行为。 【动态代理】 动态代理是Java编程中一个重要的概念,主要用于在不修改原有类代码的情况下,为类的方法添加额外的功能。CGLib通过创建...

    cglib所有jar包

    CGlib允许开发者在运行时动态创建子类,从而实现对现有类的增强或代理功能。这个"cglib所有jar包"很可能是包含CGlib库不同版本或者不同模块的集合,方便开发者根据需求选择合适版本。 在Java中,动态代理是一种常见...

    Cglib的jar文件 Cglib.zip

    Cglib是一个强大的Java代码生成库,它在运行时动态创建子类,为现有类提供扩展功能。这个库被广泛用于实现AOP(面向切面编程)中的代理机制,特别是当无法通过接口代理时,例如Java标准库中的类。Cglib是Eclipse的...

    CGLIB需要的asm-2.2.3.jar和cglib-nodep-2.2.jar

    CGLIB通过字节码技术创建一个目标类的子类,并在其中添加拦截器,实现动态代理。 2. **AOP(面向切面编程)**:CGLIB常被用于实现AOP框架,例如Spring AOP。在Spring中,如果没有使用接口,那么默认会使用CGLIB来...

    CGLib3.2.5依赖包及源码

    - **Enhancer**:这个类负责创建增强的类实例,是CGLib的核心类。 - **MethodProxy**:用于代理方法调用,内部使用ASM实现。 深入研究CGLib的源码,你可以了解如何利用Java反射、字节码操作和代理机制来实现高效、...

    cglib和asm

    CGlib常被用于创建动态代理,当目标类没有实现接口时,CGlib可以生成一个目标类的子类来实现代理。例如,在Spring AOP框架中,如果目标对象没有实现接口,Spring会使用CGlib来创建代理对象,以便在方法调用前后插入...

    CGlib动态代理类所需的jar包

    CGlib(Code Generation Library)是Java编程语言中的一个代码生成库,主要用于运行时动态创建对象和扩展类。在Java世界中,动态代理是一种强大的技术,它允许我们在运行时创建对象并实现特定接口或覆盖特定方法。...

    cglib.jar以及cglib-src.jar

    在"cglib-src-2.2.jar"中,包含了CGLIB的源代码,开发者可以深入研究其内部实现,这对于理解其工作原理和进行定制化开发非常有帮助。源码中,我们可以看到CGLIB的核心类如Enhancer、MethodInterceptor、Callback等,...

    CGLib代理模式用到的jar包

    CGLib的工作原理大致如下:首先,它会为需要代理的类生成一个子类,然后在这个子类中,针对每个方法创建一个增强方法,增强方法内部会调用MethodInterceptor的`intercept()`方法,最后在这个方法中进行实际的方法...

Global site tag (gtag.js) - Google Analytics