这样和妻子解释:Java动态代理机制详解(JDK和CGLIB( 六 )


JDK动态代理示例
现在定义两个接口Vehicle和Rechargable , Vehicle表示交通工具类 , 有drive()方法;Rechargable接口表示可充电的(工具) , 有recharge() 方法;
定义一个实现两个接口的类ElectricCar , 类图如下:
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
通过下面的代码片段 , 来为ElectricCar创建动态代理类:
package com.foo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {ElectricCar car = new ElectricCar();// 1.获取对应的ClassLoaderClassLoader classLoader = car.getClass().getClassLoader();// 2.获取ElectricCar 所实现的所有接口Class[] interfaces = car.getClass().getInterfaces();// 3.设置一个来自代理传过来的方法调用请求处理器 , 处理所有的代理对象上的方法调用InvocationHandler handler = new InvocationHandlerImpl(car);/*4.根据上面提供的信息 , 创建代理对象 在这个过程中 ,a.JDK会通过根据传入的参数信息动态地在内存中创建和.class 文件等同的字节码b.然后根据相应的字节码转换成对应的class ,c.然后调用newInstance()创建实例*/Object o = Proxy.newProxyInstance(classLoader, interfaces, handler);Vehicle vehicle = (Vehicle) o;vehicle.drive();Rechargable rechargeable = (Rechargable) o;rechargeable.recharge();}}package com.foo.proxy;/*** 交通工具接口* @author louluan*/public interface Vehicle {public void drive();}package com.foo.proxy;/*** 可充电设备接口* @author louluan*/public interface Rechargable {public void recharge();}package com.foo.proxy;/*** 电能车类 , 实现Rechargable , Vehicle接口* @author louluan*/public class ElectricCar implements Rechargable, Vehicle {@Overridepublic void drive() {System.out.println("Electric Car is Moving silently...");}@Overridepublic void recharge() {System.out.println("Electric Car is Recharging...");}}package com.foo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class InvocationHandlerImpl implements InvocationHandler {private ElectricCar car;public InvocationHandlerImpl(ElectricCar car){this.car=car;}@Overridepublic Object invoke(Object paramObject, Method paramMethod,Object[] paramArrayOfObject) throws Throwable {System.out.println("You are going to invoke "+paramMethod.getName()+" ...");paramMethod.invoke(car, null);System.out.println(paramMethod.getName()+" invocation Has Been finished...");return null;}}来看一下代码执行后的结果:
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
生成动态代理类的字节码并且保存到硬盘中:
JDK提供了sun.misc.ProxyGenerator.generateProxyClass(String proxyName,class[] interfaces) 底层方法来产生动态代理类的字节码:
下面定义了一个工具类 , 用来将生成的动态代理类保存到硬盘中:
package com.foo.proxy;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.Proxy;import sun.misc.ProxyGenerator;public class ProxyUtils {/** 将根据类信息 动态生成的二进制字节码保存到硬盘中 ,* 默认的是clazz目录下* params :clazz 需要生成动态代理类的类* proxyName : 为动态生成的代理类的名称*/public static void generateClassFile(Class clazz,String proxyName){//根据类信息和提供的代理类名称 , 生成字节码byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, clazz.getInterfaces());String paths = clazz.getResource(".").getPath();System.out.println(paths);FileOutputStream out = null;try {//保留到硬盘中out = new FileOutputStream(paths+proxyName+".class");out.write(classFile);out.flush();} catch (Exception e) {e.printStackTrace();} finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}