上章,我们知道了代理这么一种工作机制,但是有没有发现,如果我们每代理一个对象,就要写一个代理对象,那么麻不麻烦,难不难受,就有没有一个万能的代理? 当然是有的,中介可不是光能帮你租房子,还可以帮你找工作,找老婆(哈哈哈),等等等等..只有我们想不到的,没有中介做不到的;那么这章我们就来看看JAVA的万能中介:
JDK的动态代理;
废话不多说,直接看代码:
package agent;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** *@description TODO 动态代理类 *@date 2018年1月1日 *@author geYang **/public class AgentMove implements InvocationHandler { //真实角色 private Object object; public AgentMove(Object object) { this.object = object; } /** * 第一个参数: JDK的动态代理,被代理的对象必须实现的接口; * 第二个参数: Method是被代理对象接口的方法; * 第三个参数: 被代理对象接口的方法的参数; * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO 动态代理方法 if(args!=null){ for(Object obj : args){ System.out.println("真实角色参数:" + obj); } } System.out.println("动态代理前置操作"); //反射调用真实对象方法 Object invoke = method.invoke(object, args); System.out.println("动态代理后置操作"); return invoke; }}
看代码,我们会发现,这次的代理对象实现的的 java.lang.reflect.InvocationHandler 这个JDK本身的代理接口; 这块更深的地方,我也不是很懂,也没有花时间看过,只知道是这样用的;有兴趣的可以加QQ:572119197,一起讨论学习;
测试一波:
package agent;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.List;/** *@description TODO 代理测试 *@date 2018年1月1日 *@author geYang **/public class AgentTest { @SuppressWarnings("unchecked") public static void main(String[] args) { System.out.println("===========不通过代理=============="); //不同过代理来调用: Rental renal1 = new RentalImpl(); renal1.rental(); /** * 静态代理只能对指定的对象进行代理,不能通用 * */ //通过代理来调用: System.out.println("===========静态代理=============="); //抽象角色 = 代理角色 ( 真实角色 ) Rental renal = new AgentStatic(new RentalImpl()); renal.rental(); System.out.println("===========动态代理=============="); RentalImpl rentalImpl = new RentalImpl(); /*创建代理对象: * 第一个参数是: 被代理对象的类加载器; * 第二个参数是: 被代理对象的所有接口; * 第三个参数是: 自定义的代理对象; * */ Rental object = (Rental) Proxy.newProxyInstance( rentalImpl.getClass().getClassLoader(), rentalImpl.getClass().getInterfaces(), new AgentMove(rentalImpl)); object.rental(); System.out.println("===========测试其他对象代理=============="); List
通过测试,我们可以知道,动态代理,不光可以代理我们的接口,甚至List,Map...... 等等等等, 都可以让代理来完成; 在MyBatis中,SQL的实现就主要基于动态代理;
参考: