您的位置:首页 > 其它

Design pattern--代理模式

2017-06-03 16:25 162 查看

Design pattern–代理模式

代理模式是常用的设计模式之一,在retrofit2源码分析过程中,看到了动态代理的使用,非常精妙,有必要深入理解下。代理模式有两种,静态代理和动态代理。

静态代理



代理(Proxy)是一种设计模式,即通过代理对象访问目标对象,好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.看一个例子

// Subject.java
public interface Subject {
void operation();
}

// RealSubject.java
public class RealSubject implements Subject{
@Override public void operation() {
System.out.println("operation by RealSubject");
}
}

// ProxySub.java
public class ProxySub implements Subject{
Subject subject;
public ProxySub(Subject subject) {
this.subject = subject;
}
@Override public void operation() {
System.out.println("do other things");
subject.operation();
}
}

// MainActivity.java
public class MainActivity extends AppCompatActivity {

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ProxySub sub = new ProxySub(new RealSubject());
sub.operation();
}
}


ProxySub是一个代理类,目标对象是RealSubject,最终调用的是RealSubject#operation方法,但是调用RealSubject#operation前后可以做些额外的操作。

静态代理总结:

1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.

2.缺点:

因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类. 同时,一旦接口增加方法,目标对象与代理对象都要维护.

如何解决静态代理中的缺点呢?答案是使用动态代理

动态代理

通过InvocationHandler来完成动态代理

// ProxySubject.java
public class ProxySubject implements InvocationHandler{
Subject subject;
public ProxySubject(Subject subject) {
this.subject = subject;
}

@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method->" + method.getName());
return method.invoke(subject, args);
}
}

// MainActivity.java
final Subject subject = new RealSubject();
ProxySubject proxy = new ProxySubject(subject);
Subject sub = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(), proxy);
sub.operation();


运行一下:

06-03 16:05:31.683 2173-2173/com.rico.proxy I/System.out: method->operation
06-03 16:05:31.683 2173-2173/com.rico.proxy I/System.out: operation by RealSubject


调用过程大致是:newProxyInstance得到一个动态生成的代理类 $Proxy0,这个类继承了Proxy并且实现了Subject接口,所以调用$Proxy0#operation方法,实际上调用的是super.h.invoke(this, , ),也就是父类Proxy的h的invoke方法,也就是ProxySubject的invoke方法,然后通过反射method.invoke(subject, args);调用RealSubject#operation接口,有点绕,但是基本上说清楚了

查看源码发现$Proxy0正式调用getProxyClass0构建出来的,通过反射得到所有的构造方法,然后调用newInstance(cons, h);动态构建$Proxy0,传入的h正式我们ProxySubject实例

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
if (h == null) {
throw new NullPointerException();
}

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

/*
* Invoke its constructor with the designated invocation handler.
*/
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
return newInstance(cons, h);
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}


下面看下$Proxy0的源码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Manager {

private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}

public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}

@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
.booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

public final void operation() {
try {
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}


代理模式就分析这么多了,以上!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息