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

    xiaoxiao2025-09-02  179

    一:具体类

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

    转载请注明原文地址: https://ju.6miu.com/read-1302227.html
    最新回复(0)