即,动态代理是利用java反射技术,在运行时建立一个实现某些给定接口的新类。java
先定义接口api
public interface people { public String work(); }
实现该接口数组
public class Teacher implements people{ @Override public String work() { System.out.println("教书育人"); return "教书"; } }
编写代理类ide
import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class WorkHandler implements InvocationHandler { // 代理类的对象 private Object obj; public WorkHandler(){ } // 在调用这个方法的时候,会被调度到invoke方法,并将参数传入 public WorkHandler(Object obj){ this.obj = obj; } // 在调用给类的方法的时候,会被调度到invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 真实对象执行以前添加操做 // 调用obj类的method方法,而且参数为args Object invoke = method.invoke(obj, args); // 真实对象执行后添加操做 return invoke;// 返回执行的结果 } }
最后运行函数
import java.io.FileInputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Main { public static void main(String[] args){ // 要代理的对象 people people = new Teacher(); // 建立要代理的真实对象 // 进行注册 InvocationHandler handler = new WorkHandler(people); // 进行建立代理对象 // 定义一个代理对象 people proxy; // 调用Proxy.newProxyInstance方法 // 须要传入真实对象实现的接口,为下一步调用该方法作准备 // 将handler关联到invocationHandler对象,用于调度到invoke方法 // 因为返回的对象为object类型,须要进行强制类型转换,保留people接口定义的方法 // 最后一个参数要对对象进行关联,最后批量生产出对象 proxy = (people) Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler); System.out.println(proxy.work()); } }
第一个参数是运行时,建立的代理对象。this
import java.io.FileInputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main { // 须要使用static让其加载进入内存 static class myClassLoader extends ClassLoader{ private String classPath; // 获取当前类的在磁盘中保存的地址 // 经过构造函数将地址注入 public myClassLoader(String classPath){ this.classPath = classPath; } // 将文件内容加载进入内存 private byte[] loadByte(String name) throws Exception{ // 获取一个输入流, FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class"); // 获取长度 int len = fis.available(); // 定义byte数组 byte[] data = new byte[len]; // 加载进入内存 fis.read(data); // 关闭流 fis.close(); return data; } // 重写findClass方法,让加载的时候调用findClass方法 protected Class<?> findClass(String name) throws ClassNotFoundException{ try{ // 读取文件到数组中 byte[] data = loadByte(name); // 将字节码加载进入内存当中 return defineClass(name, data, 0, data.length); }catch(Exception e){ e.printStackTrace(); } return null; } } public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException { // 先初始化该类 myClassLoader classLoader = new myClassLoader("/home/ming"); // 此时会调用findClass加载Test.class加载进入内存当中 Class clazz = classLoader.loadClass("com.ming.Test"); // 实例化该类对象 Object obj = clazz.newInstance(); // 获取clazz该类方法中名称为hello,参数为空的方法。 Method helloMethod = clazz.getDeclaredMethod("helloWorld", null); // 调用该方法 // 调用obj类中的helloMethod,参数为空的方法。 helloMethod.invoke(obj, null); } }