0.掌握程度
- 什么是动态代理?
- 知道动态代理能做什么?
1.什么是动态代理?
使用jdk的反射机制,创建对象的能力,创建的是代理类的对象。而不用你创建类文件,不必写Java文件。
动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。
jdk动态代理:必须有接口,目标类必须实现接口,没有接口时,需要使用cglib动态代理。
2.知道动态代理能做什么?
-
可以在不改变原来目标方法功能的前提下,可以在代理中增强自己的功能代码。
-
程序开发中的意思:
比如:你所在的项目,有一个功能是其他人(公司的其他部门)写好的,你可以使用。 -
GoNong.class, GoNong gn = new GoNong() gn.print();
但你发现这个功能还存在缺点,不能完全满足项目的需要,eg.我需要在gn.print()执行后,需要自己在增强代码中用代理实现gn.print()调用时,增加自己代码,而不必去更改原来的GoNong文件。
3.代理模式的作用
1.功能增强:在你原有功能上,增加了额外的功能。新增的功能,叫功能增强;
2.控制访问:代理不让你访问目标,eg.商家不让你访问厂家
4.引例——通过中介机构留学
4.1.留学中介(代理):帮助美国学校招生,他是学校的代理;
代理特点:
- 1.中介和代理做的事是一致的,招生;
- 2.中介是学校的代理,学校是目标;
- 3.家长------->中介(介绍学校,办入学手续)-------->美国学校;
- 4.中介是代理,不白干活,收取费用;
- 5.代理不让你直接访问目标
4.2.为什么找中介?
- 1.中介是专业的,方便;
- 2.家长自己不能去找学校,或者高校不接受家长单独来访
4.3.实际项目开发中
你有a类,本来是调用c类的方法以完成某个功能,但c不让a调用,让b调用。
- a先访问----->代理b----->再访问c
5.实现代理的方式
5.1.静态代理
1.概念
1.代理类是自己写的,自己创建1个java类,表示代理类;
2.同时你所要代理的目标类是确定的;
2.特点:
1.实现简单;2.容易理解
3. 缺点:
1.当目标类增加,代理类可能也需要成倍的增加;
2.当你接口中的功能增加了,或者修改了,会影响众多的实现类,厂家类,代理都需要修改,影响较多。
4.实现步骤:
1.创建1个接口,定义卖U盘的方法,表示代理商和厂家做的事情;
2.创建厂家类,实现1中的方法;
3.创建代理商,就是代理,实现1中的方法;
4.创建客户端类,调用代理商的方法买U盘
5.2.动态代理
1.动态代理中目标类即使很多:
1,代理类数量可以很少;
2,当你修改了接口中的方法时,不会影响代理类;
2.动态代理:程序执行过程中,使用JDK反射机制,创建代理类对象,并动态的指定要代理目标类。
(即:动态代理是一种创建java对象的能力,让你不用创建“淘宝”类,就能创建代理类对象。)
3.在java中要想创建对象:
- 1.创建类文件,java文件编译为class;
- 2.使用构造方法,创建类的对象。
5.3.动态代理的实现-----反射包java.lang.reflect,里面有3个类:InvocationHandler、Method、Proxy
1.InvocationHandler接口(调用处理器):仅有Invoke()方法
invoke():表示代理对象要执行的功能代码,你的代理类要完成的功能就写在invoke()方法里;
代理类要完成的功能:
1.调用目标方法,执行目标方法的功能;
2.功能增强:在目标方法调用时,增强功能。
方法原型 :
参数:Object proxy:jdk创建的代理对象,无需赋值;
Method method:目标类中的方法,jdk提供method对象的;
Object[] args:目标类中的方法参数,jdk提供的;
public Object invoke(Object proxy, Method method ,Object[] args)
InvocationHandler接口:表示代理要干什么。
- 怎么用:
1.创建类实现接口InvocationHandler
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();
-
参数:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
1. ClassLoader loader 类加载器,负责向内存中加载对象的。 使用反射获取对象的ClassLoader 类a ,
a.getCalss().getClassLoader(), 目标对象的类加载器
2. Class<?>[] interfaces: 接口, 目标对象实现的接口,也是反射获取的。
3. InvocationHandler h : 我们自己写的,代理类要完成的功能。
4. 返回值:就是代理对象
6.实现动态代理的步骤
1.创建接口:定义目标类要完成的功能;
2.创建目标类实现接口
3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
-
3.1.调用目标方法 3.2.增强功能
4.使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。