代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。
上图简单代码实现(静态代理):
package com.wuhuiskiff.www.proxy.code.simple;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:31
* @Description:抽象的角色
*/
public interface Subject {
// 客户端的请求
void request();
}
package com.wuhuiskiff.www.proxy.code.simple;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:32
* @Description:
*/
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("真实角色干的事。。。");
}
}
package com.wuhuiskiff.www.proxy.code.simple;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:33
* @Description:
*/
public class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
this.preRequest();
this.realSubject.request();
this.postRequest();
}
private void preRequest(){
System.out.println("在请求之前,业务处理。。。");
}
private void postRequest(){
System.out.println("在请求之后,业务处理。。。");
}
}
package com.wuhuiskiff.www.proxy.code.simple;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:37
* @Description:
*/
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject subject = new ProxySubject(realSubject);
subject.request();
}
}
package com.wuhuiskiff.www.proxy.code.invoke;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:55
* @Description:
*/
public interface Subject {
void request();
}
package com.wuhuiskiff.www.proxy.code.invoke;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 21:56
* @Description:
*/
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("真实角色所能做的事。。。");
}
}
package com.wuhuiskiff.www.proxy.code.invoke;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 22:03
* @Description:
*/
public class DynamicSubject implements InvocationHandler {
private Object sub;
// 通过构造方法传入一个对象
public DynamicSubject(Object sub) {
this.sub = sub;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method");
// 其实调用的是被代理对象中的方法,例如这个是调用的是realSubject中的request方法
method.invoke(this.sub, args);
System.out.println("after method");
return null;
}
}
package com.wuhuiskiff.www.proxy.code.invoke;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 22:06
* @Description:
* 所谓Dynamic Proxy是这样的一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给他
* ,然后改class就宣称它实现了这些interface。你当然可以把该class的实例当做这些interface中的任何一个来用。
* 当然,这个DynamicProxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,
* 由它接管实际的工作
*/
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
InvocationHandler handler = new DynamicSubject(subject);
Class extends InvocationHandler> classType = handler.getClass();
// 生成一个代理对象,第二参数是RealSubject实现的接口
Subject subject1 = (Subject) Proxy.newProxyInstance(classType.getClassLoader(), subject.getClass().getInterfaces(),
handler);
subject1.request();
// class com.sun.proxy.$Proxy0
System.out.println(subject1.getClass());
}
}
(3)Vector的代理类:
package com.wuhuiskiff.www.proxy.code.vector;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/17 23:40
* @Description:
*/
public class VectorProxy implements InvocationHandler {
private Object object;
public VectorProxy(Object object) {
this.object = object;
}
public static Object factory(Object object){
Class> classType = object.getClass();
// 生成代理的实例
VectorProxy vectorProxy = new VectorProxy(object);
return Proxy.newProxyInstance(classType.getClassLoader(),classType.getInterfaces(),vectorProxy);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method invoke");
if(null != args){
for (Object arg:args) {
System.out.println("参数:" + arg);
}
}
Object result = method.invoke(this.object,args);
System.out.println("after method invoke");
return result;
}
public static void main(String[] args) {
List list = (List) factory(new Vector());
System.out.println(list.getClass());
// 代理类调用method.invoke方法
list.add("张山");
list.add("skiff");
System.out.println("---------------------");
list.remove(0);
}
}
代理模式的优点
代理模式的缺点
代理模式包含三个角色: