动态代理
概述
a想访问c,但不让直接访问c,而b能访问c,所以a访问b,b再访问c,这样a间接就访问了c
- 功能增强: 给其他人的类添加功能,不能直接修改对方的代码,可以通过代理增加点功能
- 控制访问: 代理类不让你访问目标,例如商家不让你直接访问厂家

静态代理
- 代理类是手工实现的,自己创建一个java类,表示代理类
- 同时你所要代理的目标类是确定的
优缺点
优点
- 实现简单
- 容易理解【用户,商家(代理卖U盘),厂家(卖u盘)】
缺点
- 当目标类增加了,代理类成倍增加 ,每个代理商家都要卖不同的目标,这样就nxn成指数性增长
- 若 售卖u盘接口增加方法,那么所有创建的代理类,厂家都得改,不灵活
实现步骤
- 创建一个接口,定义卖u盘的方法,表示你的厂家和商家正在做的事
- 创建厂家类,实现步骤1的接口
- 创建商家类,就是代理,实现步骤1的接口,并进行精美的包装
- 创建客户类,调用商家的方法买u盘
动态代理
简述: 动态代理就是不动原本的代码,对其代码进行调用,并增强功能
在静态代理中目标类有很多时,可以使用动态代理,可以避免静态代理的缺点,动态代理中目标类,代理类即使很多,就算增加了接口的功能,也不影响代理类和目标类
动态代理: 在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态的指定要代理目标类,而且不用创建对象,就可以执行对应的方法
在java中,创建对象需要创建类文件,编译为class文件,再通过构造方法创建对象,而动态代理不需要创建类文件,直接就通过构造方法直接创建对象

例1
该程序通过创建一个代理任务接口( 卖U盘),厂家实现这个接口,重写卖U盘的具体操作,创建代理类【创建一个方法,传参目标对象,返回一个代理类对象】,在测试类Test里面创建目标类对象,拿代理类
ProxySell.method()返回一个代理类对象,用代理类对象调用其代理任务方法sell(),返回目标类sell()的返回值。

代理类
package 动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//代理类
public class ProxySell {
//这里创建一个方法,用来接收工厂类,自动创建代理类,返回代理类的对象
public static SellDrive method(Factory factory) {
// Proxy.newProxyInstance()方法,创建一个代理类对象,返回值是一个Object对象(代理对象)
// 参数1:代理类的加载器(负责向内存加载对象的),参数2: 代理任务数组 参数3 创建一个(调用处理器)InvocationHandler匿名内部类 ,用实现接口的引用接收
//强转Object为代理类
SellDrive s = (SellDrive) Proxy.newProxyInstance(ProxySell.class.getClassLoader(), new Class[]{SellDrive.class}, new InvocationHandler() {
@Override
//参数1:代理类对象 参数2:目标类中的方法,jdk提供method对象的, 参数3:目标类中方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//自己要增加的功能
//判断要代理的任务,并作出不同的处理(中间商加价)
if (method.getName().equals("sell")) { //当然这里只要代理一个任务,所以也可以不用判断
System.out.println("多卖二十");
}
//上面代理商做完附加的功能,后面加上厂家(目标类)所要执行的功能
// 该方法method.invoke() ,可以执行某个目标类中的方法 参数1:目标对象 ,参数2:目标的方法参数
//也就是说现在执行的是目标类Factory类中的method方法
return method.invoke(factory, 2);
}
});
//返回一个代理类对象
return s;
}
}
例2

例3
有人找杨超唱歌,杨超越找中介公司,中介公司找代理(接口)帮他准备

执行流程 创建类 1. 代理任务接口 2.客户实现代理接口,3.代理工具(传值客户对象(接口的实现类)),返回一个接口实现类




当你的才华配不上你的野心,努力的时候到了!

浙公网安备 33010602011771号