javassist 實現接口動態代理

首先有一個學生的接口,學生的接口中有一個上交家庭做業的方法,定義很簡單java

package javaassist;

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

 

而後定義一個動態代理的對象,用以實現這個方法spring

package javaassist;
import javassist.*;
/**
 * Created by wangtengfei1 on 2017/8/2.
 * 動態代理對象
 */
public class Proxy<T> {

    private Class<T> t;//接口
    public Proxy(Class<T> 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;
    }

}

具體代碼內容,裏面已經寫了,就不作重複解讀了。bash

而後定義調用類,而且查看輸出結果this

package javaassist;

/**
 * Created by wangtengfei1 on 2017/8/2.
 */
public class Main {
    @org.junit.Test
    public void test(){
        Proxy<IStu> 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啓動的時候對象如何佔位,起到了很是好的做用。code

相關文章
相關標籤/搜索