横切关注点: 跨越应用程序多个模块的功能.java
① 、代码混乱: 每一个方法在处理核心逻辑的同时还必须兼顾其余多个关注点.编程
② 、代码分散: 以日志需求为例, 只是为了知足这个单一需求, 就不得不在多个模块里屡次重相复同的日志代码. 若是日志需求发生变化, 必须修改全部模块. 这些相似的需求包括验证, 事务等.设计模式
③ 、代码膨胀:愈来愈多的非业务需求(日志和验证)加入后, 原有的方法急剧膨胀.数组
① 、Proxy 提供用于建立动态代理类和代理对象的静态方法, 它也是全部动态代理类的父类.框架
② 、Proxy 提供了两个方法来建立动态代理类和动态代理实例ide
咱们经过代码来进行理解:模块化
接口的代码:spa
1 package cn.vincent.porxy; 2 3 public interface ArithmeticCalculator { 4 5 int add(int i, int j); 6 7 int sub(int i, int j); 8 9 void mul(int i, int j); 10 11 void div(int i, int j); 12 13 14 }
接口实现类的代码:设计
1 package cn.vincent.porxy; 2 3 public class ArithmeticCalculatorImpl implements ArithmeticCalculator { 4 5 @Override 6 7 public int add(int i, int j) { 8 9 return i + j; 10 11 } 12 13 @Override 14 15 public int sub(int i, int j) { 16 17 return i - j; 18 19 } 20 21 @Override 22 23 public void mul(int i, int j) { 24 25 System.out.println(i * j); 26 27 } 28 29 @Override 30 31 public void div(int i, int j) { 32 33 System.out.println(i / j); 34 35 } 36 37 }
动态代理类实现的代码:代理
1 package cn.vincent.porxy; 2 3 import java.lang.reflect.InvocationHandler; 4 5 import java.lang.reflect.Method; 6 7 import java.lang.reflect.Proxy; 8 9 import org.junit.Test; 10 11 12 public class TestPorxy { 13 14 /** 15 16 * 关注点: 17 18 * 19 20 * 1.获取须要被代理的目标对象。 21 22 * 23 24 * 2. Proxy.newProxyInstance(loader, interfaces, h); 25 26 * public static Object newProxyInstance(ClassLoader loader, 27 28 * Class<?>[] interfaces, 29 30 * InvocationHandler h) 31 32 * 经过使用代理类调用 静态方法 newProxyInstance 返回一个指定接口的代理类实例, 33 34 * 通常状况下其返回的是被代理的目标对象接口类型的!该接口能够将方法调用指派到指* 定的调用处理程序。 35 36 * 37 38 * 对于 newProxyInstance 方法中参数都表明什么? 39 40 * ClassLoader loader : 类加载器一般使用和被代理的对象的类加载器相同. 41 42 * 43 44 * Class<?>[] interfaces:该参数必须是一个接口类型的数组.其中若代理对象不须要 45 46 * 额外实现被代理的目标对象实现的接口外的 47 48 * 额外的接口类型,能够使用 target.getClass().getInterfaces(),来表示目标对象*实现的接口 49 50 * 51 52 * InvocationHandler h :一般使用匿名内部类的方式。 53 54 * 对于 匿名内部类InvocationHandler中的invoke 方法 中的参数。 55 56 * public Object invoke(Object proxy, Method method, Object[] args) *throws Throwable { 57 58 * 59 60 * Object result = method.invoke(target, args); 61 62 * return result; 63 64 * } 65 66 * Object proxy : 指的是正在被返回的那个代理对象,通常不使用! 67 68 * Object[] args : 传入的参数。 69 70 * Method method : 经过调用 invoke(Object obj, Object ... args),将被代 71 72 * 理的对象及参数传入, 73 74 * method.invoke(target, args); 75 76 * 实现动态代理。 77 78 */ 79 80 @Test 81 82 public void test() { 83 84 85 ArithmeticCalculator target = new ArithmeticCalculatorImpl(); 86 87 Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), 88 89 // new Class[]{ArithmeticCalculator.class}, 90 91 target.getClass().getInterfaces(), 92 93 new InvocationHandler() { 94 95 @Override 96 97 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 98 99 Object result = method.invoke(target, args); 100 101 return result; 102 103 } 104 105 }); 106 107 ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) proxy; 108 109 int result = arithmeticCalculator.add(1, 1); 110 111 112 System.out.println(result); 113 114 } 115 116 }