代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
abstract public class Subject {
abstract public void request();
}
public class RealSubject extends Subject {
public RealSubject() {}
public void request() {
System.out.println("From real subject.");
}
}
public class ProxySubject extends Subject {
private RealSubject realSubject; // 以真实角色作为代理角色的属性
public ProxySubject() {}
public void request() {// 该方法封装了真实对象的request方法
preRequest();
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request(); // 此处执行真实对象的request方法
postRequest();
}
private void preRequest() {
System.out.println("hello");
// something you want to do before requesting
}
private void postRequest() {
System.out.println("world");
// something you want to do after requesting
}
}
public class Client {
public static void main(String[] args) {
Subject sub = new ProxySubject();
sub.request();
}
}
public interface Subject
{
abstract public void request();
}
public class RealSubject implements Subject {
public RealSubject() {}
public void request() {
System.out.println("From real subject.");
}
}
/**
* 该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;此外,在该类还实现了invoke方法,该方法中的 * method.invoke(sub,args); 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象, args为执行被代理对象相应操作所需的参数。
* 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
*/
public class DynamicSubject implements InvocationHandler {
private Object sub;
public DynamicSubject() {}
public DynamicSubject(Object obj) {
sub = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling " + method);
method.invoke(sub, args);
System.out.println("after calling " + method);
return null;
}
}
public class Client {
static public void main(String[] args) throws Throwable {
RealSubject rs = new RealSubject(); // 在这里指定被代理类
InvocationHandler ds = new DynamicSubject(rs);
Class<?> cls = rs.getClass();
// 以下是一次性生成代理
// cls.getClassLoader()类装载器,运行时生成接口cls.getInterfaces(),由ds执行
Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);
subject.request();
}
}
public class VectorProxy implements InvocationHandler {
private Object proxyobj;
public VectorProxy(Object obj) {
proxyobj = obj;
}
public static Object factory(Object obj) {
Class<?> cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(), new VectorProxy(obj));
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("before calling " + method);
if (args != null) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i] + "");
}
}
Object object = method.invoke(proxyobj, args);
System.out.println("after calling " + method);
return object;
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List<String> v = (List<String>) factory(new Vector<String>(10));
v.add("New");
v.add("York");
System.out.println(v);
v.remove(0);
System.out.println(v);
}
}
void doAction();
}
public FooImpl() {}
public void doAction() {
System.out.println("in FooImp1.doAction()");
}
}
public FooImpl2() { }
public void doAction() {
System.out.println("in FooImp2.doAction()");
}
}
// 动态执行对象,需要回调的对象
private Object target;
// 支持构造子注射
public CommonInvocationHandler() {}
// 支持构造子注射
public CommonInvocationHandler(Object target) {
setTarget(target);
}
/**
* 采用setter方法注射
* @param target
*/
public void setTarget(Object target) {
this.target = target;
}
/**
* 调用proxy中指定的方法method,并传入参数列表args
* @param proxy 代理类的类型,例如定义对应method的代理接口
* @param method 被代理的方法
* @param args 调用被代理方法的参数
* @return
* @throws java.lang.Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
return method.invoke(target, args);
}
}
public static void main(String[] args) {
// 1.通用的动态代理实现
CommonInvocationHandler handler = new CommonInvocationHandler();
Foo f;
// 2.接口实现1
handler.setTarget(new FooImpl());
// 方法参数说明:代理类、代理类实现的接口列表、代理类的处理器
// 关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法
// 如果代理类没有实现指定接口列表,会抛出非法参数异常
f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
f.doAction();
// 3.接口实现2
handler.setTarget(new FooImpl2());
f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
f.doAction();
}
}