proxy mode 1. 什么是代理 2. 静态代理 3. 动态代理 3.1 什么是动态代理 3.2 jdk实现原理 3.3 代码描述
1. 什么是代理
1.1 例子解释
1. 生活中的例子,常见的商家卖东西,
商家就是代理,工厂是目标,买东西的人是客户端。
买东西不能找厂家买东西,工厂不卖,得找商家,
商家在其中形成了代理。
2. 房东--租房中介--租房人也是上面的关系
3. 程序中代理表示:a类访问c类中的方法 但是c类不让a类访问 创建一个b代理 c让b访问
1.2 作用
1.功能增强 在原有的功能上 新增了额外的功能 , 新增的功能, 叫功能增强
2.控制访问 代理类不让你访问目标 如商家不让用户访问厂家
3.在项目中使用,使用别人的代码,在不改变原来目标方法功能的前提下,
可以在代理中增强自己的功能代码
2. 静态代理
2.1 优缺点分析
代理类是自己手工实现的,自己创建一个Java类,表示代理类。你所代理的目标是确定的,好理解 缺点: 目标类增多 代理类可能成倍增加 数量太多...接口中 增加功能后 会影响代理类多实现功能...
2.2 以厂家卖u盘用代码说明
package com. lovely. static_proxy;
public interface UsbSell { float sell ( int amount) ; }
package com. lovely. static_proxy;
public class Factory implements UsbSell { @Override public float sell ( int amount) { System. out. println ( "工厂卖u盘" ) ; return 10.0f ; } }
package com. lovely. static_proxy;
public class TaoBao implements UsbSell { private Factory factory = new Factory ( ) ; @Override public float sell ( int amount) { float price = factory. sell ( amount) + 15.0f ; System. out. println ( "淘宝返回优惠券" ) ; return price; } }
package com. lovely. static_proxy; public class WeiSolder implements UsbSell { private Factory f = new Factory ( ) ; @Override public float sell ( int amount) { return f. sell ( amount) + 1.0f ; } }
package com. lovely. static_proxy; public class BuyMain { public static void main ( String[ ] args) { TaoBao tb = new TaoBao ( ) ; float price = tb. sell ( 10 ) ; System. out. println ( "经过代理taobao 价格 " + price) ; WeiSolder w = new WeiSolder ( ) ; price = w. sell ( 10 ) ; System. out. println ( "经过代理微商 价格 " + price) ; } }
3. 动态代理
3.1 什么是动态代理
概念在程序执行过程中,使用jdk的反射机制,创建代理类对象(无需写代理类了),并动态的指定要代理目标类(厂家)。又 : 动态代理是一种创建Java对象的能力,让你不用创建代理类,就能创建代理类对象。代理目标是活动的,可设置的给不同的目标随时创建代理
优点:解决静态代理的弊端在静态代理中目标类很多的时候 可使用动态代理 修改接口中的方法 不会影响代理类
3.2 jdk实现原理
要求:jdk的动态代理 目标类与代理类必须实现相同的接口,才可代理jdk动态代理实现:InvocationHandler: 只有一个invoke()方法,里面写代理类实现的功能 1. 调用目标类方法 2. 实现功能增强public Object invoke(Object proxy, Method method, Object[] args)InvocationHandler 接口:表示你的代理要干什么。使用: 1. 创建类实现接口 InvocationHandler2. 重写invoke方法,把原来静态代理中代理类要完成的功能写在invoke中Method 类 method.invoke(目标对象,"参数值")Proxy 类 使用proxy类的方法 表示创建对象 代替newProxy.newProxyInstance(more args...); 创建代理对象public static Object newProxyInstace(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)代理目标类, 创建代理类对象(返回值)参数1. ClassLoader loader 类加载器,负责向内存中加载对象。目标对象的类加载器。a.getClass().getClassLoader()2. Class<?>[] interfaces 目标对象实现的接口3. InvocationHandler 代理类要完成的功能
3.3 代码描述
package com. lovely. dynamite_proxy;
public interface UsbSell { public abstract float sell ( int amount) ; }
package com. lovely. dynamite_proxy; public class UsbKingFactory implements UsbSell { @Override public float sell ( int amount) { System. out. println ( "工厂实现卖u盘,每个" + 10.0f ) ; return 10.0f ; } }
package com. lovely. dynamite_proxy; import java. lang. reflect. InvocationHandler;
import java. lang. reflect. Method;
public class MyInvocationHandler implements InvocationHandler { private Object target = null; public MyInvocationHandler ( Object target) { this . target = target; } public Object invoke ( Object proxy, Method method, Object[ ] args) throws Throwable { Object returnValue = method. invoke ( target, args) ; if ( target != null) { float price = ( float ) returnValue; price += 20.0f ; returnValue = price; } System. out. println ( "这里调用目标方法,还可做其它操作,如写一些其它功能" ) ; return returnValue; } }
package com. lovely. dynamite_proxy; import java. lang. reflect. Proxy; public class BuyMain { public static void main ( String[ ] args) { UsbSell usbKing = new UsbKingFactory ( ) ; MyInvocationHandler handler = new MyInvocationHandler ( usbKing) ; UsbSell proxy = ( UsbSell) Proxy. newProxyInstance ( UsbKingFactory. class . getClassLoader ( ) , UsbKingFactory. class . getInterfaces ( ) , handler) ; float price = proxy. sell ( 1 ) ; System. out. println ( "价格为 " + price) ; } }
工厂实现卖u盘,每个10.0
这里调用目标方法,还可做其它操作,如写一些其它功能
价格为 30.0
cglib(code generating libray)动态代理: 第三方的工具库 创建代理对象原理是继承: cglib通过继承目标类 创建子类 重写方法 对功能修改对于无接口的类 使用cglib实现cglib在spring mybatis中使用较多