写点什么

代理模式,薪资翻倍

用户头像
Android架构
关注
发布于: 1 小时前

public Proxy() {


//构造函数中初始化一个要被代理的对象


subject = new RealSubject("default");


}


/*可以构造函数中传入被代理者/


public Proxy(Subject subject) {


this.subject = subject;


}


@Override


public void request() {


beforeRequest();


subject.request();


afterRequest();


}


private void beforeRequest() {


System.out.println("在访问实际的被代理者对象方法之前做一些事情");


}


private void afterRequest() {


System.out.println("在访问实际的被代理者对象方法之后做一些事情");


}


}


public class Client {


public static void main(String[] args) {


Proxy subjectProxy = new Proxy();


subjectProxy.request();


System.out.println();


subjectProxy = new Proxy(new RealSubject("new"));


subjectProxy.request();


}


}


输出:



客户端在使用的时候,对 RealSubject 的请求完全由 Proxy 代为处理,Proxy 代理请求的时候可以在之前或之后执行自己的个性化的方法。对于实际的被代理者对象 RealSubject 的创建,可以完全放在 Proxy 的构造函数内部,也可以外部创建好之后再传入代理对象,这需要根据实际需求确定,如果你想要屏蔽客户端对真实的被代理者角色的访问,那么这时可以将需要的参数传入代理者内部来创建对象。


强制代理


顾名思义,强制代理就是要强制使用代理对真实对象进行访问,如果不使用代理则没有办法访问到被代理的对象。之所以这么做,是因为在某些情况下,我们的被代理者身份安全级别比较高,不希望别人直接访问到真实对象,比如我写了一个算法类,或者是系统的一个核心类,不希望客户直接去调用它,而必须通过代理来访问。


示例代码改造如下:


public class RealSubject implements Subject {


private String name;


private static Proxy proxy;


private RealSubject(String name) {


this.name= name;


}


public static Proxy getProxy() {


if (proxy == null) {


proxy = new Proxy(new RealSubject("param"));


}


return proxy;


}


@Override


public void request() {


System.out.println("执行实际的被代理者对象的方法 "+name);


}


}


public class Client {


public static void main(String[] args) {


Proxy proxy = RealSubject.getProxy();


proxy.request();


}


}


在上面代码中,我们直接将 RealSubject 的构造函数私有化,这样客户端连 new 一个被代理者对象的机会都没有,也就没有办法去直接调用被代理者对象的任何方法,客户端只能通过静态方法 getProxy()获取到一个代理对象,通过该对象进行访问。这就好比你要想访问明星,则先要跟他的经纪人打交道。


虚拟代理


这里提到的“虚拟代理”其实就是延迟初始化,并没有听上去那么复杂,至于为啥叫这个名字,我也不清楚是谁最初这样叫的,可能是业内约定成俗了,可以不用管它,我们知道是啥就行了。


示例代码:


public class Proxy implements Subject {


private Subject subject;


public Proxy(Subject subject) {


this.subject = subject;


}


@Override


public void request() {


if (subject == null) {


subject = new RealSubject("param");


}


subject.request();


}


}


代码跟之前的唯一区别就是将对象的初始化放到了调用的时候,这对于创建开销比较大的对象是有用的,因为你不需要一开始就去创建它们,只有当真正被使用到的时候才会创建。


动态代理


java 的 api 为我们提供了两个类可以实现代理模式:Proxy 和 InvocationHandler, 通过利用 Java 提供的类实现的代理称为动态代理,下面是类图:



其中 Proxy 是一个类,由 jdk 提供,客户端无需实现,InvocationHandler 是一个接口,由 jdk 提供,客户端只需要创建实现类实现该接口即可。


示例代码:


public class MyInvocationHandler implements InvocationHandler {


private Object object;


public MyInvocationHandler(Object object) {


this.object = object;


}


@Override


public Object invoke(Object proxy, Method method, Object[] a


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


rgs) throws Throwable {


return method.invoke(this.object, args);


}


}


public class DynamicProxy {


public static <T> T newProxyInstance(Subject subject) {


ClassLoader classLoader = subject.getClass().getClassLoader();


Class<?>[] interfaces = subject.getClass().getInterfaces();


InvocationHandler handler = new MyInvocationHandler(subject);


return (T) Proxy.newProxyInstance(classLoader, interfaces, handler);


}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
代理模式,薪资翻倍