有什么不对

时间:2019-12-25 03:05:55

标签: java proxy cglib dynamic-proxy

我正在学习cglib代理,当我使用在DemoApplication类中声明的Person类作为增强器的超类的目标时,会出现这样的错误。

这是我的代码

public class DemoApplication {
public static void main(String[] args) {
    new DemoApplication();
}

DemoApplication(){
    Person person = new Person();
    MyMethodInterceptor myMethodInterceptor = new MyMethodInterceptor(person);
    person = (Person) myMethodInterceptor.getProxyInstance();
    person.say();

}
class Person{
    void say(){
        System.out.println("I am saying");
    }
}
class MyMethodInterceptor implements MethodInterceptor {

    Object target;

    MyMethodInterceptor(Object target){
        this.target = target;
    }

    Object getProxyInstance(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Person.class);
        enhancer.setCallback(this);
        enhancer.setClassLoader(DemoApplication.class.getClassLoader());
        return enhancer.create();
    }

     @Override
     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
         System.out.println("Before....");
         return method.invoke(target,objects);
     }
 }
}

这是错误

Exception in thread "main" java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:1033)
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:724)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:358)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569)
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:384)
at com.shao.demo.DemoApplication$MyMethodInterceptor.getProxyInstance(DemoApplication.java:53)
at com.shao.demo.DemoApplication.<init>(DemoApplication.java:25)
at com.shao.demo.DemoApplication.main(DemoApplication.java:14)

但是当我在名为Person.java的新类文件中声明Person类时 会有正确的输出

Before....
I am saying

1 个答案:

答案 0 :(得分:1)

您正在使用内部类进行扩展,将源代码修改为(将public static附加到Person类中):

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class DemoApplication {
    public DemoApplication() {
        Person person = new Person();
        MyMethodInterceptor myMethodInterceptor = new MyMethodInterceptor(person);
        person = (Person) myMethodInterceptor.getProxyInstance();
        person.say();

    }

    public static class Person {
        void say() {
            System.out.println("I am saying");
        }
    }

    public static class MyMethodInterceptor implements MethodInterceptor {

        Object target;

        MyMethodInterceptor(Object target) {
            this.target = target;
        }

        Object getProxyInstance() {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Person.class);
            enhancer.setCallback(this);
            enhancer.setClassLoader(DemoApplication.class.getClassLoader());
            return enhancer.create();
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("Before....");
            return method.invoke(target, objects);
        }
    }

    public static void main(String[] args) {
        DemoApplication app = new DemoApplication();
    }
}

输出:

Before....
I am saying