前言
这章非常重要可以称作Java2e的原理吧代理
第一节 代理模式和静态代理
• 代理(Proxy):代替处理
– 代理服务器
– 代理经纪人
总结:把请求交给代理对象处理
• 代理模式
– Proxy Pattern, 23个经典模式的一种,又称委托模式
– 为目标对象提供(包装)了一个代理,这个代理可以控制对目标对象的访问
• 外界不用直接访问目标对象,而是访问代理对象,由代理对象再调用目标对象
• 代理对象中可以添加监控和审查处理
– David Wheeler(函数的发明者):All problems in computer science can be solved by another level of indirection。
(计算机科学中的所有问题都可以通过另一个层次的间接寻址来解决)
• Java代理:静态代理和动态代理
• 静态代理
– 代理对象持有目标对象的句柄(代理对象可以操作目标对象)
– 所有调用目标对象的方法,都调用代理对象的方法
– 对每个方法,需要静态编码(理解简单,但代码繁琐)
自我总结:句柄可以当作类似对象那样
总结
• 了解代理模式
• 了解Java的静态代理模式
– 隐藏实际的目标对象
– 对方法的实现前后可以进行前置处理和后置处理
第二节 动态代理
• 动态代理
– 对目标对象的方法每次被调用,进行动态拦截
拦截后丢到代理器处理
一般流程图
• 代理处理器
– 持有目标对象的句柄
– 实现InvocationHandler接口
• 实现invoke方法
• 所有的代理对象方法调用,都会转发到invoke方法来
• invoke的形参method,就是指代理对象方法的调用
• 在invoke内部,可以根据method,使用目标对象不同的方法来响应请求
• 代理对象
– 根据给定的接口,由Proxy类自动生成的对象
– 类型 com.sun.proxy.$Proxy0,继承自java.lang.reflect.Proxy
– 通常和目标对象实现同样的接口(可另实现其他的接口)
– 实现多个接口
• 接口的排序非常重要
• 当多个接口里面有方法同名,则默认以第一个接口的方法调用
• Therefore, when a duplicate method is invoked on a proxy instance, the Method object for the method in the foremost interface that contains the method (either directly or inherited through a superinterface) in the proxy class’s list of interfaces is passed to the invocation handler’s invoke method, regardless of the reference type through which the method invocation occurred.
因此,当在代理实例上调用重复方法时,包含该方法的最前面接口中方法的方法对象
代理类的接口列表中的(直接或通过上级接口继承的)传递给调用处理程序的invoke方法,而不管如何通过引用发生的方法的类型。
代码:
代理类的调用处理器
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理类的调用处理器
*/
class ProxyHandler implements InvocationHandler{
private Subject subject;
public ProxyHandler(Subject subject){
this.subject = subject;
}
//此函数在代理对象调用任何一个方法时都会被调用。
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(proxy.getClass().getName());
//定义预处理的工作,当然你也可以根据 method 的不同进行不同的预处理工作
System.out.println("====before====");
Object result = method.