Java中的代理模式
代理模式是一种常见的设计模式,它可以为其他对象提供一个代理,从而控制这个对象的访问。代理模式在Java中也有广泛的应用,下面我们来介绍一下Java中的代理模式。
代理模式的定义
代理模式是一种结构型设计模式,它允许对象在不改变其原有的接口的情况下,为其他对象提供一个代理。代理对象可以在原有对象的基础上增加一些额外的功能,比如权限控制、性能优化等。
代理模式的实现
在Java中,代理模式有两种实现方式:静态代理和动态代理。
静态代理
静态代理是指在编译时就已经确定代理对象的类型,代理对象和被代理对象在编译时就已经确定。静态代理需要手动编写代理类,具体实现如下:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject request");
}
}
public class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("ProxySubject before request");
realSubject.request();
System.out.println("ProxySubject after request");
}
}
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.request();
}
}
上面的代码中,Subject是被代理对象的接口,RealSubject是被代理对象,ProxySubject是代理对象。在ProxySubject中,我们通过构造函数传入了RealSubject对象,在request()方法中调用了realSubject.request()方法,并在前后增加了一些额外的逻辑。
动态代理
动态代理是指在运行时根据需要动态创建代理对象,代理对象和被代理对象在运行时才确定。Java中的动态代理主要有两种实现方式:基于接口的动态代理和基于类的动态代理。
基于接口的动态代理
基于接口的动态代理是指代理对象和被代理对象都必须实现同一个接口,代理对象在运行时动态生成,具体实现如下:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject request");
}
}
public class DynamicProxySubject implements InvocationHandler {
private Object target;
public DynamicProxySubject(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxySubject before request");
Object result = method.invoke(target, args);
System.out.println("DynamicProxySubject after request");
return result;
}
}
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
DynamicProxySubject dynamicProxySubject = new DynamicProxySubject(realSubject);
Subject proxySubject = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
dynamicProxySubject);
proxySubject.request();
}
}
上面的代码中,我们首先定义了Subject接口和RealSubject类,然后定义了一个实现了InvocationHandler接口的DynamicProxySubject类,它的构造函数中传入了被代理对象,invoke()方法中调用被代理对象的方法,并在前后增加了一些额外的逻辑。在Client类中,我们通过Proxy.newProxyInstance()方法动态生成了代理对象,并调用了它的request()方法。
基于类的动态代理
基于类的动态代理是指代理对象和被代理对象不需要实现同一个接口,代理对象在运行时动态生成,具体实现如下:
public class RealSubject {
public void request() {
System.out.println("RealSubject request");
}
}
public class DynamicProxySubject extends RealSubject {
@Override
public void request() {
System.out.println("DynamicProxySubject before request");
super.request();
System.out.println("DynamicProxySubject after request");
}
}
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
DynamicProxySubject dynamicProxySubject = new DynamicProxySubject();
dynamicProxySubject.request();
}
}
上面的代码中,我们首先定义了RealSubject类,然后定义了一个继承了RealSubject的DynamicProxySubject类,在request()方法中调用了super.request()方法,并在前后增加了一些额外的逻辑。在Client类中,我们创建了一个RealSubject对象和一个DynamicProxySubject对象,并调用了它们的request()方法。
代理模式的优缺点
代理模式的优点是可以在不改变原有对象的情况下增加一些额外的功能,比如权限控制、性能优化等。代理模式的缺点是会增加代码的复杂度,特别是在使用动态代理时更加明显。
总结
代理模式是一种常见的设计模式,在Java中有两种实现方式:静态代理和动态代理。静态代理需要手动编写代理类,而动态代理可以在运行时动态生成代理对象。代理模式的优点是可以在不改变原有对象的情况下增加一些额外的功能,缺点是会增加代码的复杂度。