紧接着上节,为了解决静态代理的问题,出现了动态代理, 假设动态代理是一个代购公司,私有变量Object factory为动态生成的具体的真实对象,可代购对应的产品 。代码:ide
/** * 动态代理 */ public class DynamicProxyCompanyC implements InvocationHandler { // 被代理的对象,即真实对象 private Object factory; public Object getFactory() { return factory; } public void setFactory(Object factory) { this.factory = factory; } // 经过proxy获取动态代理的对象 public Object getProxyInstance() { //第三个参数是InvocationHandler,传入自身说明此proxy对象是和自身的invoke方法合做的,代理对象方法调用会通过下面invoke的加强 return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this); } @Override /**经过动态代理对象对方法进行加强 * @param proxy 代理对象 * @param method 要加强的方法(拦截的方法) * @param args 方法参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { dosomeThingBefore(); Object ret = method.invoke(factory, args);// 经过反射机制调用方法 dosomeThingAfter(); return ret; } public void dosomeThingBefore() { System.out.println("售前服务,负责产品调研,兴趣爱好"); } public void dosomeThingAfter() { System.out.println("售后服务,包装丶送货上门一条龙服务"); } }
测试类:测试
public class Proxytest { public static void main(String[] args) { // 代购公司C,负责代购全部产品 DynamicProxyCompanyC proxy = new DynamicProxyCompanyC(); // 日本有家A公司生产男性用品 ManToolFactory dogToolFactory = new AManFactory(); // 代购A公司的产品 proxy.setFactory(dogToolFactory); // 建立A公司的代理对象 ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance(); // 代理对象完成代购男性用品 proxyObject.saleManTool("D"); System.out.println("--------------"); // 日本有家B公司生产女性用品 WomanToolFactory womanToolFactory = new BWomanFactory(); // 代购B公司的产品 proxy.setFactory(womanToolFactory); // 建立B公司的代理对象 WomanToolFactory proxyObject1 = (WomanToolFactory) proxy.getProxyInstance(); // 代理对象完成代购女性用品 proxyObject1.saleWomanTool(1.8); } } // 售前服务,负责产品调研,兴趣爱好 // A工厂出售男性用品,D罩杯 // 售后服务,包装丶送货上门一条龙服务 // -------------- // 售前服务,负责产品调研,兴趣爱好 // B工厂生产女性用品,长度1.8米 // 售后服务,包装丶送货上门一条龙服务
1.实现了InvocationHandler接口;this
2.经过proxy获取动态代理的对象。spa
根据咱们此例子里面来讲,动态代理就相似一个代购公司,可代购全部产品,须要购买哪一个产品的时候就实例化一个真实对象(如测试类须要男性用品则将接口引用指向真实对象AManFactory),根据真实对象建立代理对象来执行具体的方法,图解以下:代理
接下来咱们先初步看一下JDK里面的Proxy这个源码。
这个注释是说Proxy提供个一个静态方法来建立代理类和代理实例,它也是全部由此方法建立的代理类的父类。
静态方法建立代理实例即方法newProxyInstance(ClassLoader loader,Class<?>[]interfaces,InvocationHandler h);调试
InvocationHandler 是一个接口,定义了invoke(Object proxy, Method method, Object[] args)方法code
总的来讲Proxy专门负责new一个实例(真实对象),而具体方法作什么,业务怎样加强就由InvocationHandler(抽象对象)的invoke方法(抽象对象即接口定义的方法)来决定。对象
接下来咱们要搞清楚动态代理的底层原理,首先咱们调试一下test类,会发现 ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance()中建立的proxyObject 对象类名是$Proxy0,是ManToolFactory接口的实现类。可是咱们项目工程里面却没有$Proxy0这个类,那它到底是怎么出现的,下节讲解。接口