javassist 实现接口动态代理

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

首先有一个学生的接口,学生的接口中有一个上交家庭作业的方法,定义很简单

package javaassist;

/**
 * Created by wangtengfei1 on 2017/8/2.
 * 学生接口
 */
public interface IStu {
    /**
     * 交作业
     */
    public void handupTask();
}

 

然后定义一个动态代理的对象,用以实现这个方法

package javaassist;
import javassist.*;
/**
 * Created by wangtengfei1 on 2017/8/2.
 * 动态代理对象
 */
public class Proxy {

    private Class t;//接口
    public Proxy(Class t){
        this.t = t;
    }

    private static final String PROXYFREFIX = "$Proxy";//生成的代理对象名称前缀
    private static final String PROXYSUFFIX = "Impl";//生成的代理对象名称前缀

    //生成代理对象
    public T getProxyOject(){
        T proxyObject = null;
        try {
            ClassPool pool = ClassPool.getDefault();
            CtClass ctClass = pool.makeClass(getPackageName() + getProxyObjectName()); //创建代理类对象

            //设置代理类的接口
            CtClass interf = pool.getCtClass(getPackageName()+"."+t.getSimpleName()); //获取代理对象的接口类
            CtClass[] interfaces = new CtClass[]{interf};
            ctClass.setInterfaces(interfaces);

            CtMethod[] methods = interf.getDeclaredMethods(); //代理类的所有方法
            CtField[] fields = interf.getDeclaredFields();//代理类的所有属性
            for(CtMethod method:methods){
                String methodName = method.getName();
                CtMethod cm = new CtMethod(method.getReturnType(), methodName, method.getParameterTypes(), ctClass);
                cm.setBody("System.out.println(\"hand up my homework from proxy Object\");");
                ctClass.addMethod(cm);
            }
            Class aClass = ctClass.toClass();
            proxyObject=(T) aClass.newInstance();
        } catch (NotFoundException |CannotCompileException |IllegalAccessException |InstantiationException e) {
            e.printStackTrace();
        }
        return proxyObject;
    }

    //获取包名
    public String getPackageName(){
        Package aPackage = t.getPackage();
        String packageName = aPackage.getName();
        return packageName;
    }

    //获取代理对象的名称
    public String getProxyObjectName(){
        return PROXYFREFIX+t.getSimpleName()+PROXYSUFFIX;
    }

}

具体代码内容,里面已经写了,就不做重复解读了。

然后定义调用类,并且查看输出结果

package javaassist;

/**
 * Created by wangtengfei1 on 2017/8/2.
 */
public class Main {
    @org.junit.Test
    public void test(){
        Proxy proxy = new Proxy<>(IStu.class);
        IStu proxyOject = proxy.getProxyOject();
        System.out.println("proxy Object name:"+proxyOject.getClass().getName());
        proxyOject.handupTask();
    }
}

输出结果如下:

proxy Object name:javaassist$ProxyIStuImpl
hand up my homework from proxy Object

Process finished with exit code 0

 

此代理对象定义的比较简单,并且实现也比较单一,但是对于理解spring启动的时候对象如何占位,起到了非常好的作用。

转载于:https://my.oschina.net/u/2457218/blog/1499778

你可能感兴趣的:(javassist 实现接口动态代理)