模拟JDK动态代理

[亡魂溺海] 提交于 2019-12-02 14:37:05
package dumu.test.proxy.demo;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * @author dumu 2019/10/27
 */
public class Proxy {

    public static Object newProxyInstance(Class clazz, InvocationHanlder h) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        String infName = clazz.getSimpleName();
        String hanlderName = h.getClass().getSimpleName();

        String content = "";
        String line = "\n";
        String tab = "\t";
        //定义package
        String packageContent = "package dumu.test.proxy.demo;" + line;
        //import
        String importContent = "import " + clazz.getName() + ";" + line + "import dumu.test.proxy.demo." + hanlderName + ";" + line + "import java.lang.reflect.Method;" + line ;
        // 类
        String clazzFirstLineContent = "public class $ProxyLuban implements " + infName + "{" + line;
        //属性
        String filedContent = tab + "private " + hanlderName + " target;" + line;
        //构造方法
        String constructorContent = tab + "public $ProxyLuban (" + hanlderName + " target){" + line
                + tab + tab + "this.target =target;"
                + line + tab + "}" + line;


        String methodContent = "";

        Method[] methods = clazz.getDeclaredMethods();



        for (Method method : methods) {
            //String
            String returnTypeName = method.getReturnType().getSimpleName();
            //query
            String methodName = method.getName();
            // [String.class===class]
            Class args[] = method.getParameterTypes();
            String argsContent = "";
            String paramsContent = "";
            int flag = 0;
            for (Class arg : args) {
                //String
                String temp = arg.getSimpleName();
                //String
                //String p0
                argsContent += temp + " p" + flag + ",";
                //p0
                paramsContent += "p" + flag + ",";
                flag++;
            }
            if (argsContent.length() > 0) {
                argsContent = argsContent.substring(0, argsContent.lastIndexOf(",") - 1);
                paramsContent = paramsContent.substring(0, paramsContent.lastIndexOf(",") - 1);
            }

            methodContent += tab + "public " + returnTypeName + " " + methodName + "(" + argsContent + ") throws Exception {" + line +
                    tab + tab + "Method method = this.getClass().getMethod(\"" + methodName + "\");" + line +
                    tab + tab + "return" +"("+returnTypeName+")"+"target.invoke(method,null);"+line+
                    tab + "}" + line;

        }

        content += packageContent + importContent + clazzFirstLineContent + filedContent + constructorContent + methodContent + "}";


        File file = new File("/Users/edz/Downloads/dumu/test/proxy/demo/$ProxyLuban.java");

        try {
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file);
            fw.write(content);
            fw.flush();
            fw.close();
        } catch (Exception e) {
            System.out.println(e);
        }

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
        Iterable units = fileMgr.getJavaFileObjects(file);

        JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
        t.call();

//        //Class.forName()
//        //fileMgr.close();
//
//        URL[] urls = new URL[]{new URL("file:Users/edz/Downloads")};
//        URLClassLoader urlClassLoader = new URLClassLoader(urls);
//        Class cls = urlClassLoader.loadClass("file:/Users/edz/Downloads/$ProxyLuban.class");


//        return $ProxyLuban.class.getConstructor(clazz).newInstance(h);

        Constructor<$ProxyLuban> constructor = $ProxyLuban.class.getConstructor(h.getClass());
        return constructor.newInstance(h);


//        Class cls = URLClassLoader.getSystemClassLoader().loadClass("$ProxyLuban");
//        Constructor constructor = cls.getConstructor(clazz);
//        Object o  = constructor.newInstance(h);
//        return  o;
    }
}

//自定义InvovationHandler

package dumu.test.proxy.demo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author dumu 2019/10/27
 */
public interface InvocationHanlder {

    public Object invoke(Method method,Object[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException;
}

//接口

package dumu.test.proxy.demo;

/**
 * @author dumu 2019/10/27
 */
public interface DaoMapper {

    String select(String a) throws Exception;
}

 

package dumu.test.proxy.demo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author dumu 2019/10/27
 */
public class DaoInvocationHanlder implements InvocationHanlder {

    private DaoService daoService;

    public DaoInvocationHanlder(DaoService daoService){
        this.daoService = daoService;
    }


    @Override
    public Object invoke(Method method, Object[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {


        System.out.println("DaoInvocationHanlder");

        return "DaoInvocationHanlder";
    }
}
//调用
package dumu.test.proxy.demo;

import org.junit.Assert;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;

/**
 * @author dumu 2019/10/27
 */
public class Test {

    @org.junit.Test
    public void testProxy() throws Exception {
        DaoMapper o = (DaoMapper)Proxy.newProxyInstance(DaoMapper.class, new DaoInvocationHanlder(new DaoService()));
        o.select("12");
        Assert.assertNotNull(o);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!