代理模式可以理解成面向切面
面向切面:在原有的功能上扩展功能,不修改原有的代码
静态代理
开闭原则:对软件应当开放扩展功能,关闭修改源码
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,一般还会做一些额外操作
- 客户:访问代理对象的人
案例:我(客户)要去租房(抽象角色),我去找了中介(代理角色)帮我找房子.包租婆(真实角色)把出租的事交给中介,并不会见你.中介除了帮包租婆出租房子,还必须收取中介费,带你看房(扩展功能)
这个案例并不难理解,客户想要实现抽象角色(接口),就必须找包租婆(正常想法).但真实角色吧业务交给代理角色去做,你就必须通过代理角色租房子(自己代入这些角色对应的身份)
实现代码:中文别吐槽
//客户
public class proxy {
public static void main(String[] args) {
代理角色 中介 = new 代理角色(new lord()); //把包租婆丢给中介去实现
中介.rend(); //中介带你去找包租婆要出租的房子(并不会看到包租婆)
中介.toll();
}
}
//抽象角色(租房子这件事)
interface rent {
void rend();
}
//真实角色(包租婆)
class lord implements rent{
//接口方法
public void rend() {
System.out.println("包租婆出租");
}
}
//代理角色(中介)
class 代理角色 implements rent{
lord lord;
public 代理角色(lord lord) {
this.lord = lord;
}
//接口方法,客户调用中介的出租,中介又去调用包租婆的出租(中介还能做其他事)
public void rend() {
lord.rend();
lookRoom(); //可以在源码基础上扩展业务
}
//扩展业务
public void lookRoom(){
System.out.println("看房子");
}
public void toll(){
System.out.println("收取中介费");
}
}
静态优点:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共业务
- 公共交给代理角色,实现业务分工
- 公共业务扩展时候,方便集中管理
静态缺点:一个真实角色就会产生一个代理角色,代码翻倍,一个实现类一个代理角色(一个包租婆就一个中介)
动态代理
理解完静态代理再来看动态!
案例:说白了就是在调用时候,可以实现不同的包租婆(静态缺点:一个中介只能代理一个包租婆)
应为底层都是通过反射实现的,你给什么实现类,就能拿到对应的方法
- 动态代理和静态代理角色一样
- 动态代理的代理类都是动态生成的,不是直接写好的
- 动态代理分为两大类:基于接口,基于类
- 基于接口–JDK代理[本次代码]
- 基于类:cglib
- java字节码实现:javasist
需要了解的两个类:proxy(代理), InvocationHandler(调用处理程序)
//动态代理的核心代码基本是不变的
public class proxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public proxyInvocationHandler(Object target) {//传入你需要实现的真实对象
this.target = target;
}
//整合真是对象的所有方法和扩展业务,通过Proxy获取
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName()); //扩展业务,通过反射获取方法名
return method.invoke(target, args);//可以获取真实对象的所有方法
}
//生成得到代理类(代理角色)
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), //获取加载器
target.getClass().getInterfaces(), this); //获取真实对象的接口
}
public void log(String msg) {
System.out.println("执行了" + msg + "方法");
}
}
//抽象角色
interface rent {
void rend();
}
//真实角色
class lord1 implements rent{
public void rend() {
System.out.println("包租婆1出租");
}
}
//客户
class Client{
public static void main(String[] args) {
//不存在代理角色,设置真实角色
proxyInvocationHandler pih = new proxyInvocationHandler(new lord1());
rent1 proxy = (rent1) pih.getProxy();
proxy.rend();
}
}
优点:
- 静态代理的优点全有
- 一个动态代理类代理的事一个借口,一般就是对应一类业务
- 一个动态代理可以代理多个类,只要实现接口一致
如果有错,一定要在评论区指出(我也只是整理笔记)
以上都是浅谈代理模式思想:如果想深入了解专业知识,也应该对您有帮助,整理不易,看完点赞