java----------->代理模式
目录
什么是代理模式?
为什么会有代理模式?
怎么写代理模式?
实现代理模式总共需要三步:
什么是代理模式?
代理模式:给目标对象提供一个代理对象,并且由代理对象控制目标对象的引用
代理就是不允许用户访问当前核心类
为什么会有代理模式?
假设有一个类,类中写一个转账的方法:
zhuanzhang(nameA, nameB, money)
此时,一个test类就就可以直接访问该方法,这时有很多安全漏洞:a,b,name都没有经过验证就直接执行程序,完全没有考虑过a,b是否存在,money是否足够的问题
而如果把对参数的验证写到转账方法所在的类中,转账的核心方法可能就不是转账而是验证,而且代码的更改很难做到
因为当原有的写好的逻辑当中,需要增加新的功能时,由于当前整个逻辑是通顺的,不能轻易改动代码,此时,就需要代理模式解决该问题,还能够增强原有的逻辑功能
所以,代理对象相当于用户与核心方法之间的一个中介
怎么写代理模式?
如上面的例子,若转账类生成转账对象,又有代理类生成代理对象,
由代理对象控制对转账对象的引用,而此时用户在调用过程中能调用的方法都是代理方法,能看到的对象都是代理对象,
也就是说,目标对象/核心方法不对外提供引用
实现代理模式总共需要三步:
- 代理类实现对目标类的引用
- 知道目标类的核心方法是什么
- 调用目标类的核心方法
1.代理类如何控制目标类的引用?
就是去创建对象
一般情况下代理对象也要设置成private
用户不被允许访问当前的转账方法
2.怎样知道目标类的核心方法是什么?
可以利用反射
Proxy.newProxyInstance(o.getClass().getClassLoader(),
o.getClass().getInterfaces(),h:this);//此时,o表示Object类型参数变量
//o.getClass().getClassLoader() 获取目标类的构造器
//o.getClass().getInterfaces() 获取目标类实现的接口
3.怎么调用目标类的核心方法?
只要在代理对象中写一个方法,该方法调用目标方法
对于用户来说,就像是直接调用了目标对象,
对于代理对象来说,实际上是调用了当前目标对象的类
当用户类去创建代理对象时,代理对象中就创建好了目标对象
通过method.invoke()调用核心方法(该方法为method包中自带),如图:
代理模式的核心功能
- 通过代理对象间接访问目标对象,通过防止用户直接访问目标对象,给系统带来不必要的复杂 性,即直接调用转账对象里的方法就有可能会出现前文所说的风险
- 通过代理业务对原有业务进行增强
代理模式分类
代理模式分为静态代理和动态代理
静态代理和动态代理的一大区别在于代理类和代理对象的关系
如图:
静态代理:
- 优点:实现起来较简单,易于理解和维护。
- 缺点:代理类需要为每个接口都进行单独实现,如果接口方法发生变化,代理类也需要相应地修改,可扩展性较差。
且静态代理严格意义上不算代理
动态代理:
动态代理有两种实现方式:
<1>jdk <2>cglib
这篇只介绍jdk
如何实现动态代理中代理类对代理对象一对多而代理对象对目标对象一对一的情况?
答:Object
在代理对象的方法中添加一个Object类型参数,参数对应要调用的目标方法即可实现
但其知道目标对象是什么,但是不知道目标对象里的方法是什么
如果使用接口并直接在接口后面添加方法名,此时破坏了开闭原则
此时就需要利用反射知道目标的核心方法
补:
类是构建对象的模板,先必须创建出类来,才能把对象给创建出来
接口(Interface) 是一种抽象类型,是抽象方法的集合。一个类通过实现接口的方式,从而继承接口的抽象方法。接口的定义方式与类相似,但它们属于不同的概念。接口不能被实例化,但可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
对于代理模式的使用,常见的有,远程代理、虚拟代理、保护代理等等