java动态代理-自己实现

来源:互联网 发布:微信签到抽积分 源码 编辑:程序博客网 时间:2024/05/20 05:05

一、被代理类

public interface Product {    void method() throws Throwable;}public class ProductImpl implements Product{    public void method() {        System.out.println("执行方法");    }}

二、MyInvocationHandler

public interface MyInvocationHandler {    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}public class MyProxyHandler implements MyInvocationHandler {    private Product product;    public MyProxyHandler(Product product){        this.product = product;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        before();        Object object = method.invoke(product,args);        after();        return object;    }    public void before(){        System.out.println("前调用");    }    public void after(){        System.out.println("后调用");    }}
三、MyProxy的代码

public class MyProxy {    public static final String RT = "\r\n";    public static final String PROXY_CLASS_NAME = "$Proxy0";    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,MyInvocationHandler handler)            throws Exception{        Method[] methods = interfaces[0].getMethods();        //1、用流的方式创建一个Java文件        String proxyClass = MyProxy.class.getPackage() + ";" + RT                + "import java.lang.reflect.Method;" + RT                + "public class "+ PROXY_CLASS_NAME +" implements " + interfaces[0].getName() + "{" + RT                + "MyInvocationHandler h;" + RT                + "public "+ PROXY_CLASS_NAME + "(MyInvocationHandler h) {" +RT                + "this.h = h ;" + RT + "}"                + getMethodString(methods,interfaces[0]) + RT + "}";        try {            String rootPath = "F:\\IdeaProjects\\proxy\\";            //2、把类生成文件            String fileName = rootPath + PROXY_CLASS_NAME +  ".java";            File file = new File(fileName);            FileWriter fw = new FileWriter(file);            fw.write(proxyClass);            fw.flush();            fw.close();            //3、编译Java文件            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();            StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);            Iterable units = fileManager.getJavaFileObjects(fileName);            JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);            task.call();            fileManager.close();            //4、把class加载到内存            MyClassLoader loader1 = new MyClassLoader(rootPath);            Class proxy0Class = loader1.findClass(PROXY_CLASS_NAME);            Constructor con = proxy0Class.getConstructor(MyInvocationHandler.class);            Object object = con.newInstance(handler);            //5、删除生成的代理类            File classFile = new File(rootPath + PROXY_CLASS_NAME +".class");            if(classFile.exists()){                classFile.delete();            }            if(file.exists()){                file.delete();            }            return object;        }catch (IOException e){            e.printStackTrace();        }        return null;    }    private static String getMethodString(Method[] methods,Class cla){        String proxyStr = "";        for (Method method : methods){            proxyStr += "public void  " + method.getName() + "() throws Throwable {" + RT                    + "Method md = " + cla.getName() + ".class.getMethod( \"" + method.getName()                    + "\",new Class[]{});" + RT                    + "this.h.invoke(this,md,null);" + RT                    + "}" + RT;        }        return proxyStr;    }}

四、类加载器

public class MyClassLoader extends ClassLoader{    private File file;    MyClassLoader(String path){        file = new File(path);    }    @Override    protected Class<?> findClass(String name) throws ClassNotFoundException {        if(file != null){            File clazzFile = new File(file,name + ".class");            if(clazzFile.exists()){                FileInputStream inputStream = null;                try {                    inputStream = new FileInputStream(clazzFile);                    ByteArrayOutputStream baos = new ByteArrayOutputStream();                    byte[] buffer = new byte[1024];                    int len;                    while ((len = inputStream.read(buffer)) != -1){                        baos.write(buffer,0,len);                    }                    return defineClass(MyClassLoader.class.getPackage().getName()+ "." + name,baos.toByteArray(),0,baos.size());                } catch (FileNotFoundException e) {                    e.printStackTrace();                } catch (IOException e) {                    e.printStackTrace();                }finally {                    if(inputStream != null){                        try {                            inputStream.close();                        } catch (IOException e) {                            e.printStackTrace();                        }                    }                }            }        }        return super.findClass(name);    }}

五、调用类

public class MyHandle {    public static void main(String[] args) throws Throwable{        Product product = (Product) MyProxy.newProxyInstance(Product.class.getClassLoader(),                new Class[]{Product.class}, new MyProxyHandler(new ProductImpl()));        product.method();    }}



原创粉丝点击