代理模式一般涉及到的角色有
1、抽象角色:声明真实对象和代理对象的共同接口
2、代理角色:代理对象角色内部含有对真实对象的引用,从而可以操纵真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象:同时代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
3、真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
写道
package com.test.proxy;
/**
* 抽象角色:声明真实对象和代理对象的共同接口
* @author Administrator
*
*/
public abstract class Subject {
public abstract void request();
}
/**
* 抽象角色:声明真实对象和代理对象的共同接口
* @author Administrator
*
*/
public abstract class Subject {
public abstract void request();
}
package com.test.proxy;
/**
* 真实角色
* @author Administrator
*
*/
public class RealObject extends Subject {
@Override
public void request() {
System.out.println("from real subject");
}
}
package com.test.proxy;
/**
* 代理角色
* @author Administrator
*
*/
public class ProxySubject extends Subject {
private RealObject realSubject;
@Override
public void request() {
this.preRequest();
if(null == realSubject)
{
realSubject = new RealObject();
}
realSubject.request();
this.afterRequest();
}
private void preRequest()
{
System.out.println("pre request");
}
private void afterRequest()
{
System.out.println("after request");
}
}
写道
package com.test.proxy;
/**
* 客户端
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
/**
* 客户端
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
由上述代码可以看出,客户实际调用的是RealSubject累的request方法,现在用 ProxySubject来代理realsubject同样达到了目的,同时还封装了其它的方法(preReuqest 、afterRequest)可以处理一些其他的问题
另外如果按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致累的急剧膨胀:此外如果事先不知道真实角色,该如何使用代理呢?这个问题可以使用Java的动态代理解决。
java 的动态代理位于java.lang.reflect包下,一般主要涉及到一下两个类:
1、interface InvocationHandler 该接口仅定义了一个方法
public object invoke(Object object,Method method,Object[] args);
在实际应用时,第一个参数object一般是指代理类,method是被代理的方法,如上例中的request(),args为该法方法的参数数组。这个抽象方法在代理类中动态实现。
2、 Proxy:该类即为动态代理类,作用类似于上面的ProxyObject(代理角色),其主要包含以下内容:
protected Proxy(InvocationHandler h):构造函数用于给内部的h赋值。
static Class getProxyClass(ClassLoader classLoader,Class[] interfaces):获得一个代理类,其中classloader是类装载器,interfaces是真实类拥有的所有接口的数组。
static Object newProxyInstance(ClassLoader classLoader,Class[] interfaces,InvocationHandler h)
返回代理类的实例,返回后的代理类可以当做被代理类来使用。
package com.test.dynamicproxy;
public interface Subject {
void request();
}
package com.test.dynamicproxy;
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("fron real subject");
}
}
package com.test.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyObject implements InvocationHandler {
private Object object;
public ProxyObject(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("pre request");
method.invoke(object, args);
System.out.println("after request");
return null;
}
}
package com.test.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
RealSubject subject = new RealSubject();
InvocationHandler in = new ProxyObject(subject);
Class<?> clazz = subject.getClass();
Subject object = (Subject)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), in);
object.request();
}
}