android代理

代理模式

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
通过引入代理对象的方式来间接访问目标对象,防止直接访问目标对象给系统带来的不必要复杂性。
通过代理对象对原有的业务增强。
代理模式一般会有三个角色:
抽象角色: 指代理角色和真实角色对外提供的公共方法,一般为一个接口
真实角色: 需要实现抽象角色接口,定义了真实角色所要实现的业务逻辑,以便供代理角色调用。
代理角色: 需要实现抽象角色接口,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。将统一的流程控制都放到代理角色中处理。
访问者不再访问真实角色,而是去访问代理角色。

静态代理

需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。一般来说,被代理对象和代理对象是一对一的关系,当然一个代理对象对应多个被代理对象也是可以的。
一对一则会出现时静态代理对象量多、代码量大,从而导致代码复杂,可维护性差的问题,一对多则代理对象会出现扩展能力差的问题。

动态代理

在使用时再创建代理类和实例。
只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码,更强的灵活性。
效率低,相比静态代理中直接调用目标对象方法,动态代理则需要先通过Java反射机制 间接调用目标对象方法。
应用场景局限,Java 的单继承特性(每个代理类都继承了 Proxy 类),即只能针对接口创建代理类,不能针对类创建代理类。

java动态代理

InvocationHandler
给动态代理类实现的,负责处理被代理对象的操作的
Proxy
用来创建动态代理类实例对象的,因为只有得到了这个对象我们才能调用那些需要代理的方法。

public class Company implements InvocationHandler {

    /*持有的真实对象*/
    private Object factory;

    public Object getFactory() {
        return factory;
    }

    public void setFactory(Object factory) {
        this.factory = factory;
    }

    /*通过Proxy获得动态代理对象*/
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),this);
    }

    /*通过动态代理对象方法进行增强*/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        doSthBefore();
        Object result = method.invoke(factory, args);
        doSthAfter();
        return result;
    }
 	/*前置处理器*/
    private void doSthBefore() {
        System.out.println("先做点事情");
    }
    /*后置处理器*/
    private void doSthAfter() {
        System.out.println("方法调用完了,再做点事情");
    }
   
}

动态代理实现原理

Proxy.newProxyInstance的方法

 		/*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);

其实调用的是下面方法

 /**
     * Generate a proxy class.  Must call the checkProxyAccess method
     * to perform permission checks before calling this.
     */
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        return proxyClassCache.get(loader, interfaces);
    }

下面是这个缓存的实现

 /**
     * a cache of proxy classes
     */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

再看一下ProxyClassFactory的代码

 	// Android-changed: Generate the proxy directly instead of calling
    // through to ProxyGenerator.
    List<Method> methods = getMethods(interfaces);
    Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
    validateReturnTypes(methods);
    List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);

    Method[] methodsArray = methods.toArray(new Method[methods.size()]);
    Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);

    /*
    * Choose a name for the proxy class to generate.
    */
    long num = nextUniqueNumber.getAndIncrement();
    String proxyName = proxyPkg + proxyClassNamePrefix + num;

    return generateProxy(proxyName, interfaces, loader, methodsArray,
                                     exceptionsArray);

注意这里面和java是不一样的
java中使用的是

 public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2)

下面再接着看构造

 final Constructor<?> cons = cl.getConstructor(constructorParams);

其实调用的是下面方法

/**
 * Returns the constructor with the given parameters if it is defined by this class;
 * {@code null} otherwise. This may return a non-public member.
 *
 * @param args the types of the parameters to the constructor.
 */
@FastNative
private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);

最后返回的是

return cons.newInstance(new Object[]{h});

h就是InvocationHandler

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值