动态代理的具体实现
实际开发中,有时候需要对一个类进行功能扩展,但要求变动尽可能地小,扩展性尽可能地强,这时候可以用代理。
①静态代理,前面也有写,很粗浅,希望有用( 静态代理),如图:
②动态代理,代理类不是静态定义的,是程序动态生成的,代码简洁,且兼顾扩展性,如图:
代码如下:
1 package proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.lang.reflect.Proxy; 7 8 /** 9 * @author o_0sky 10 * @date 2019/2/15 20:44 11 */ 12 public class proxyDemo { 13 public static void main(String[] args) { 14 //创建被代理类对象 15 final Bao bao = new Bao(); 16 /** 17 * 构建代理类对象 18 */ 19 ClassLoader loader= bao.getClass().getClassLoader(); 20 ; //获取类加载器 21 Class<?>[] interfaces = bao.getClass().getInterfaces();//获取实现接口 22 InvocationHandler h = new InvocationHandler() { 23 /** 24 * 代理类每调用一次方法,InvocationHandler.invoke就执行一次 25 * 代理类的所有方法都是有InvocationHandle.invoke生成的 26 * @param proxy 代理类当前对象 27 * @param method 代理类对象当前调用的方法 28 * @param args 代理类对象调用方法传入的参数(可能有多个参数) 29 * @return 30 * @throws Exception 31 */ 32 public Object invoke(Object proxy, Method method, Object[] args) throws Exception { 33 String methodName = method.getName();//代理类调用哪个方法,方法名就是谁 34 if ("sing".equals(methodName)) { 35 /*arg[0]为Object类型 36 Object类型不能直接强转为int类型 37 可以转Long再由Long转为Int类型 38 也可以用楼主这种方法 39 * */ 40 41 Integer money = Integer.parseInt(args[0].toString()); 42 //控制条件达到 43 if (money > 20) { 44 bao.sing(money); 45 } else { 46 System.out.println("你这点钱很难让我给你办事啊!"); 47 } 48 49 } 50 if("show".equals(methodName)){ 51 Integer money = Integer.parseInt(args[0].toString()); 52 //控制条件达到 53 if (money > 20) { 54 bao.show(money); 55 } else { 56 System.out.println("你这点钱很难让我给你办事啊!"); 57 } 58 } 59 return null; 60 } 61 62 63 };
//强转 64 Actor proxy = (Actor) Proxy.newProxyInstance(loader,interfaces,h); 65 proxy.sing(21); 66 } 67 }
执行结果如下(调用的sing方法):