java动态代理-自己实现

一、被代理类

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();
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值