1. 简介
代理模式属于设计模式中的结构型模式,有静态代理和动态代理两种实现方式。代理模式使用代理类来控制访问委托类中方法或者增强委托类的功能。
2. 实现
静态代理
静态代理即是代理类在编译期间已知。
UML类图
如上图所示:
-
Subject
接口定义了代理类Proxy
和委托类RealSubject
共同的方法request()
-
RealSubject
委托类,它是被代理和控制访问的对象 -
Proxy
代理类引用了RealSubject
的对象,实现了对它的访问控制
代码实现
interface Subject{
void request();
}
class RealSubject implements Subject{
@Override
public void request() {
System.out.println("request");
}
public void run(){
System.out.println("run");
}
}
class Proxy implements Subject{
private Subject subject;
public Proxy(Subject subject){
this.subject = subject;
}
@Override
public void request() {
System.out.println("before");
subject.request();
System.out.println("after");
}
}
动态代理
动态代理即是代理类在运行期间产生,这个需要用到Java的反射机制,使用JDK的java.lang.reflect
这个包中的一个接口和类:
-
InvocationHandler
接口是个调用处理器,通过重写invoke(Object proxy, Method method, Object[] args)
方法来对委托类中的方法进行控制访问。 -
Proxy
类提供几个静态方法:-
getProxyClass(ClassLoader loader, Class<?>... interfaces)
方法通过传入类加载器和委托类实现的接口这些参数来生成一个代理类,生成的代理类继承了Proxy
并且实现了所有委托类的接口 -
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
方法创建一个代理类实例
-
代码实现
interface Subject{
void request();
}
/委托类
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("request");
}
public void run(){
System.out.println("run");
}
}
/调用处理器
class ProxyInvocationHandler implements InvocationHandler{
private Object realSubject;
public ProxyInvocationHandler(Object realSubject){
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object returnObject = method.invoke(realSubject, args);
System.out.println("after");
return returnObject;
}
}
class ProxyClass {
private Class<?> proxy;
private ProxyInvocationHandler handler;
private Object realSubject;
public ProxyClass(ProxyInvocationHandler handler, Object realSubject) {
this.handler = handler;
this.realSubject = realSubject;
this.proxy = productProxyClass();
}
/产生代理类
private Class<?> productProxyClass() {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?>[] interfaces = realSubject.getClass().getInterfaces();
return Proxy.getProxyClass(loader, interfaces);
}
public Class<?> getProxy() {
return proxy;
}
/创建代理类对象
public Object newInstance() {
try {
Constructor constructor = proxy.getDeclaredConstructor(InvocationHandler.class);
return constructor.newInstance(handler);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
public class DynamicProxy{
public static void main(String[] args){
/创建委托类对象
Subject realSubject = new RealSubject();
/创建代理类调用处理器
ProxyInvocationHandler handler = new ProxyInvocationHandler(realSubject);
ProxyClass proxyClass = new ProxyClass(handler, realSubject);
生成代理类对象
Subject proxy = (Subject) proxyClass.newInstance();
proxy.request();
}
}