设计模式(二)代理模式

2023-03-19  本文已影响0人  文泰ChrisTwain

1.简介

Provide a surrogate or placeholder for another object to control access to it.为一个对象提供一种代理以控制对该对象的访问
---《Design Patterns: Elements of Reusable Object-Oriented Software设计模式-可复用的面向对象软件元素》

代理模式属于结构型设计模式:代理类和真实类实现同一个接口,代理类持有真实类引用,通过代理对象调用真实对象。类图如下所示:


proxy.png

2.静态代理实现

/**
 * 被代理类接口声明
 */
public interface ISubject {
    void request();
}

/**
 * 定义被代理类
 */
public class SubjectImpl implements ISubject {
    @Override
    public void request() {
        Log.d("SubjectImpl", "被代理类");
    }
}

/**
 * 定义代理类
 */
public class Proxy implements ISubject {

    private ISubject subject;

    public Proxy(ISubject subject) {
        this.subject = subject;
    }

    @Override
    public void request() {
        subject.request();
    }
}

// 客户端调用
ISubject proxy = new Proxy(new SubjectImpl());
proxy.request();

3.动态代理实现

public class DynamicProxy implements InvocationHandler {
    private Object proxyObject;

    // 传入被代理类作为参数,生成代理对象。将代理对象与此InvocationHandler关联,代理对象调用代理方法时将调用InvocationHandler#invoke()
    public <T> T newProxyInstance(Object proxyObject) {
        this.proxyObject = proxyObject;
        return (T) Proxy.newProxyInstance(proxyObject.getClass().getClassLoader(),
                proxyObject.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result = method.invoke(proxyObject, args);
        // doing somthing else.
        return result;
    }
}

// 客户端调用,复用前面静态代理中定义的接口和被代理类
DynamicProxy dynamicProxy = new DynamicProxy();
ISubject proxy = dynamicProxy.newProxyInstance(new SubjectImpl());
proxy.request();
  @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
  public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
        Proxy.newProxyInstance(        // 通过JDK动态代理的方式生成网络请求接口的实例类
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                Platform platform = Platform.get();
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);    // 解析请求接口的注解和方法参数构造请求参数,生成OkHttp call
              }
            });
  }
private void init(Context context) {
    try {
        Class<?> cls = Class.forName("com.me.test.MyManager");  // Framework层提供管理类和接口
        Class callbackCls = Class.forName("com.me.test.MyManager$IMyCallback");
        Constructor constructorMyManager = cls.getConstructor(new Class[] {Context.class, callbackCls});

        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
        Object objectCallback = Proxy.newProxyInstance(HostAbility.class.getClassLoader(),
                new Class[] {callbackCls}, myInvocationHandler);  // APK中完成接口实例化

        Object myManager = constructorMyManager.newInstance(new Object[] {context, objectCallback});  // 将生成的接口传给系统层
        RealManager realManager = (RealManager) myManager;  // apk可调用系统提供的管理类达到一定控制,系统被调用后也可控制触发apk相关逻辑在InvocationHandler中
    } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException
            | InvocationTargetException | InstantiationException e) {
        Logger.e(TAG, "exception in reflecting callback");
    }
}

private class MyInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // checking
        if (args == null || args.length < LENGTH) {
            Logger.e(TAG, "unexpected callback!");
            return null;
        }

        // 获取参数
        long p1 = ((Long) args[0]);
        int p2 = ((Integer) args[1]);
        int p3 = ((Integer) args[2]);

        // doing something 由系统在Framework层调用接口后回调到APK中执行,达到由系统层控制上层业务
        return null;
    }
}
参考

refactoringguru-代理模式
从Retrofit看懂动态代理模式
一定能看懂的 Retrofit 最详细的源码解析
深入理解Retrofit动态代理
枚举、动态代理的原理

上一篇下一篇

猜你喜欢

热点阅读