动态代理两个类Proxy和InvocationHandler的模拟实现

一:具体类

 Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

 InvocationHandler

 Proxy

二:具体运用

 在不变原基础方法的情况下,对其开头 结尾,加事务,日志,拦截器,等。。。。

动态代理具体的运用,如spring中的关键技术AOP,

三:代码模拟Proxy 和 InvocationHandler

需求:在不变原方法的情况下,在方法前后分别加上日志

第一阶段

新建接口类,

package com.wem.Dome;

/**
 * Created by Administrator on 2016-08-13.
 */
public interface Vehicle {
    public void run();
}

新建实现类

package com.wem.Dome;

/**
 * Created by Administrator on 2016-08-13.
 */
public class Car implements Vehicle {
    @Override
    public void run() {
        System.out.println("轰隆隆的启动了");
    }
}
在不变原方法的情况下,也就是说不能再修改Car中的run方法了,可以想到的方法是,如下方法


package com.wem.Dome;

/**
 * Created by Administrator on 2016-08-15.
 */
public class AddLog {
    public void addlog(Vehicle vehicle){
        System.out.println("start log");
        Vehicle v = vehicle;
        v.run();
        System.out.println("stop log");
    }
}
但是,如果我想再添加一个事务呢?或者,在不变原方法的情况下拦截某些数据,那么得继续增加类,或者增加方法来做这样的操作, 那么根据这个问题,想能不能建立一个代理类,来做这些事情。

MyProxy

package com.wem.Dome;

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

/**
 * Created by Administrator on 2016-08-13.
 */
public class MyProxy {
    public static Object newProxyInstance(Class interf,MyInvocationHandler h) {
        String rn = "\r\n";
        //获取接口中有多少方法
        Method[] methods =interf.getMethods();
        String MethodStr = "";
        //组合方法
        for(Method m :methods){
            MethodStr = "    @Override " +rn+
                        "    public "+m.getReturnType().getName()+" "+m.getName()+"(){" + rn +
                        "       try{"+ rn +
                        "             Method md ="+interf.getName()+".class.getMethod(\""+m.getName()+"\");"+ rn +
                        "             h.invoke(this,md);"+ rn +
                        "       }catch(Exception e){" +rn+
                        "             e.printStackTrace();"+rn+
                        "       }"+rn+
                        "    }"+rn;
        }
        String str ="import java.lang.reflect.Method;"+ rn +
                "import com.wem.Dome.MyInvocationHandler;"+ rn +
                "public class $Proxy implements "+interf.getName()+"{ " + rn +
                "   MyInvocationHandler h;"+ rn +
                "   public $Proxy(MyInvocationHandler h){" + rn +
                "           this.h =h;" + rn+
                "   }"+ rn+
                MethodStr+
                "}";
         String fileName = "D:/src/$Proxy.java";
        File file = new File(fileName);
        try {
            //生成.java文件,
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(str.getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
            //生成.class文件
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);
            Iterable units = fileManager.getJavaFileObjects(fileName);
            JavaCompiler.CompilationTask t = compiler.getTask(null,fileManager,null,null,null,units);
            t.call();
            fileManager.close();

            //获取class文件的路径
            URL[] urls = new URL[]{new URL("file:/"+"D:/src/")};
            //class加载器
            URLClassLoader url = new URLClassLoader(urls);
            //把class文件加入内存中
            Class c = url.loadClass("$Proxy");
            System.out.println(c);
            //获取类的有参数的构造函数
            Constructor ctr = c.getConstructor(MyInvocationHandler.class);
            //根据构造函数获取生成对象,传入对象h
            Object p = ctr.newInstance(h);
            return p;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
建立MyInvocationHandler
package com.wem.Dome;

import java.lang.reflect.Method;

/**
 * Created by Administrator on 2016-08-13.
 */
public interface MyInvocationHandler {
    public Object invoke(Object o, Method method);
}
创建 MyInvocationHandler实现类

package com.wem.Dome;

import java.lang.reflect.Method;

/**
 * Created by Administrator on 2016-08-13.
 */
public class LogMyInvocationHandler implements MyInvocationHandler {
    private Object object;
    public LogMyInvocationHandler(Object o){
        this.object = o;
    }
    @Override
    public Object invoke(Object o, Method method) {
        Object restul= null;
        try {
            //开启日志
            System.out.println("Start log");
            //以本例为例,method = public abstract void com.wem.Dome.Vehicle.run()
            restul = method.invoke(object);
            //日志结束
            System.out.println("Stop log");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return restul;
    }
}

效果显示

main方法

public static void main(String[] arge){
            Car car = new Car();
            MyInvocationHandler lm = new LogMyInvocationHandler(car);
            Vehicle v =(Vehicle) MyProxy.newProxyInstance(Vehicle.class,lm);
            v.run();
        }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值