动态代理(理解):基于反射机制。
掌握程度:
1.什么是动态代理?
? 使用jdk的反射机制,创建对象的能力,创建的是代理类的对象。而不用你创建类文件。不用谢java文件。
? 动态:在程序执行时,调用JDK提供的方法才能创建代理类的对象。
? jdk动态代理,必须有接口,目标类必须实现接口,没有接口时,需要使用cylib动态代理。
2.知道动态代理能做什么?
? 可以在不改变原来目标方法功能的前提下,可以在代理中增强自己的功能代码。
? 程序开发中的意思。
? 比如:你所在的项目中,有一个功能是其他人(公司的其他部门,其他小组的人)写好的,你可以使用。
? GoNong.class , GoNong gn = new GoNong(), gn,print();
? 你发现这个功能,现在还缺点,不能完全满足我项目的需要,我需要在gn.print()执行后,需要自己在增强代码。
? 用代理实现gn.print()调用时,增加自己代理,而不用去改变原来GoNang文件。
1.代理
代购,中介,换ip,商家等等
比如有一家美国的大学,可以对全世界招生,留学中介(代理)
留学中介(代理):帮助这家美国的学校招生,中介是学校的代理,中介是代理学校完成招生功能。
? 代理特点:
? 1.中介和代理他们要做的事情是一致的:招生。
? 2.中介是学校代理,学校是目标。
? 3.家长–中介(学校介绍,办入学手续)–美国学校。
? 4.中介是代理,不能白干活,需要收取费用
? 5.代理不让你访问到目标。
? 为什么要找中介?
? 1.中介是种业的,方便
? 2.家长现在不能自己去找学校,加载没有能力访问学校。或者灭国学校不接收个人来访。
? 买东西都是商家卖,商家是某个商品的代理,你个人买东西,肯定不会让你接触到厂家的。
2.在开发中也会有这样的情况,你有a类,本来是调用c类的方法,完成某个功能。但是c不然a调用。
a-----不能调用c的方法
在a和c之间 创建一个b代理,c让b访问
a----访问b----访问c
? 实际的例子:登录,注册有验证码,验证码是手机短信。
? 中国移动,联通能发短信。
? 中国移动,联通能有子公司,或者关联公司,他们面向社会提供短信的发送功能。
? 张三项目发送短信----子公司,或者关联公司—中国移动,联通
2.代理模式
**代理模式:**代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。-
? ------百度百科《代理模式》
换句话说,使用代理对象,是为了在不修改目标对象的基础上,增强主业务逻辑。
客户类真正的想要访问的对象是目标对象,但客户类真正可以访问的对象是代理对象。
客户类对目标对象的访问是通过访问代理对象来实现的,当然,代理类与目标类要实现同一个接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ueVSIS1j-1653224592560)(C:\Users\lenovo\Documents\Tencent Files\1551302120\FileRecv\MobileFile\BBEABC1368A55B1EAFFB94310E2ECB4A.png)]
2.1使用代理模式的作用:
? 1.功能增强 :在你原有的功能上,增强了额外的功能。新增加的功能,叫做功能增强。
? 2.控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。
2.2实现代理的方式:
2.21.静态代理:
? 1)代理类是自己手工实现的,自己创建一个java类,表示代理类。
? 2)同时你所要代理的目标类是确定(固定)的。
? 特点:1)实现简单 2)容易理解。
? 缺点:当你的项目中,目标类和代理类很多时候,有以下的缺点:
? 1)当目标类增加了,代理类可能也需要成倍的增加。代理类数量过多。
? 2)当你的接口中功能增加了,或者修改了,会影响众多的实现类,厂家类,代理都需要修改,影响比较大
? 例子:模拟一个用户购买U盘的行为。
? 用户是客户端类。
*商家:代理,代理某个品牌的U盘*
? 厂家:目标类
? 三者的关系:用户(客户端)—商家(代理)—厂家(目标)
? 实现步骤:
? 1.创建一个接口,定义卖U盘的方法,表示你的厂家和商家做的事情。
? 2.创建厂家类,实现1步骤的接口
? 3.创建商家,就是代理,也需要实现1步骤中的接口。
? *4.创建客户端类,调用商家的方法买一个U盘。
package com.bjpowernode.service;
public interface UsbSell {
float sell(int amount);
}
package com.bjpowernode.factory;
import com.bjpowernode.service.UsbSell;
public class UsbKingFactory implements UsbSell {
@Override
public float sell(int amount) {
System.out.println("目标类中的方法调用,UsbKingFactory中的 sell");
return 85.0f;
}
}
package com.bjpowernode.shangjia;
import com.bjpowernode.factory.UsbKingFactory;
import com.bjpowernode.service.UsbSell;
public class TaoBao implements UsbSell {
private UsbKingFactory factory = new UsbKingFactory();
@Override
public float sell(int amount) {
float price = factory.sell(amount);
price = price + 25;
System.out.println("淘宝商家,给你返一个优惠券,或者红包");
return price;
}
}
package com.bjpowernode;
import com.bjpowernode.shangjia.TaoBao;
public class ShopMain {
public static void main(String[] args) {
TaoBao taoBao = new TaoBao();
float price = taoBao.sell(1);
System.out.println("通过淘宝的商家,够哦买U盘单价:"+price);
}
}
2.2.2 动态代理
在静态dialing中目标类很多时候,可以使用动态代理,避免静态代理的缺点。
动态代理中目标类即使很多,1)代理类数量可以很少 2)当你修改了接口中的方法时,不会影响代理类。
动态代理:在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态的指定要代理目标类。
? 换句话说,动态代理是一种创建java对象的能力,让你不用创建TaoBao类,就能创建代理类对象。
在java中,要想创建对象: 1)创建类文件,java文件编译为class 2)使用构造方法,创建类的对象
动态代理定义
动态代理是指代理类对象在程序运行时由JVM跟腱炎反射机制动态生成的。动态代理不需要定义代理类的.java源文件。
动态代理其实就是jdk运行期间,动态创建class字节码并加载到JVM.
动态代理的实现方式常用的有两种:使用JDK代理代理,与通过CGLIB动态代理。
动态代理的实现:1.jdk动态代理 2.cglib动态代理
1)jdk动态代理:使用java反射包中的类和对象实现动态代理的功能。
? 反射包java.lang.reflect ,里面有三个类:Proxy,Method和InovcationHandler.
2)cglib动态代理:cglib是第三方的工具库,创建代理对象。
? cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法,实现功能的 修改。
? 因为cglib是继承,重写方法,所以要求目标类不能是final的,方法也不能是final的。
? cglib的要求目标类比较宽松,只要能继承就可以了。cglib在狠毒的框架中使用,比如mybatis,soring框架中都有使用。
jdk动态代理:
? 1.反射,Method类,表示方法。类中的方法。通过Method可以执行某个方法。
? 2.jdk动态代理的实现:
? 反射包java.lang.reflect ,里面有三个类:Proxy,Method和InovcationHandler.
? 1)InovcationHandler.接口:就一个方法invoke()
? invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在invoke()方法中。
? 代理类完成的功能:1)调用目标方法,执行目标方法的功能。
? 2)功能增强,在目标方法调用时,增强功能。
? 方法原型:public Object invoke(Object proxy, Method method, Object[] args)
? 参数:
? Object proxy:jdk创建的代理对象,无需赋值。
? Method method:目标类中的方法,jdk提供method对象的
? Object[] args:目标类中方法的参数
? 怎么用:1.创建类实现接口InovcationHandler
? 2.重写invoke()方法,把原来静态代理中代理类要完成的功能,卸载这里。
? 2)Method类:表示方法的,确切的说就是目标类中的方法。
? 作用:通过Method可以执行某个目标类的方法,Method.invoke();
? method.invoke(目标对象,方法的参数)
? Object ret =method.invoke(service2,“李四”);
? 说明:method.invoke()就是用来执行目标方法的,等同于静态代理中的
? //向厂家发送订单,告诉产假,我买了U盘,厂家发货
? float price = factory.sell(amount);//厂家的价格
? 3)Proxy类:核心的对象,创建代理对象。之前创建对象都是new类的构造方法()
? 现在我们是使用proxy类的方法,代替new的使用。
? 方法:静态方法newProxyInstance()
? 作用是:创建代理对象,等同于静态代理中的TaoBao taoBao = new TaoBao();
? 参数:
? 1.ClassLoader loader 类加载器,负责向内存中加载对象的。使用反射获取对象的ClassLoader类a,a.getClass().getClassLoader(),目标对象的类加载器
? 2.Class<?>[] interfaces:接口,目标对象实现的解耦,也是反射获取的。
? 3.InvocationHandler h:我们自己写的,代理类要完成的功能
? 返回值:就是代理对象。
? public static Object newProxyInstance(ClassLoader loader,
? Class<?>[] interfaces,
? InvocationHandler h)
3.实现动态代理的步骤:
? 1)创建接口,定义目标类要完成的功能
? 2)创建目标类实现接口
? 3)创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能(调用目标方法,增强功能)
? 4)使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。
|