代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对实际对象的访问。代理对象充当了实际对象的替代品,可以在调用实际对象的方法之前或之后添加额外的逻辑。以下是代理模式的应用方法:
静态代理
定义接口或父类:首先定义一个接口或父类,被代理的对象和代理对象需要一起实现相同的接口或继承相同的父类。
创建代理对象:创建代理对象,该对象持有被代理对象的实例,并在调用其方法前后添加额外的逻辑。
使用代理对象:客户端通过代理对象来访问实际对象,代理对象负责调用实际对象的方法并返回结果。
示例代码(Java):
```java
public interface TeacherDao {
void teach();
}
public class TeacherDaoImpl implements TeacherDao {
@Override
public void teach() {
System.out.println("Teaching...");
}
}
public class TeacherDaoProxy implements TeacherDao {
private TeacherDaoImpl teacherDao;
public TeacherDaoProxy(TeacherDaoImpl teacherDao) {
this.teacherDao = teacherDao;
}
@Override
public void teach() {
System.out.println("Proxy is preparing to teach...");
teacherDao.teach();
System.out.println("Proxy has finished teaching...");
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDaoImpl);
teacherDaoProxy.teach();
}
}
```
动态代理(JDK代理)
定义接口:定义一个接口,代理类和真实对象都需要实现该接口。
创建InvocationHandler:实现`InvocationHandler`接口,该接口包含对实际对象方法的调用逻辑。
创建代理对象:使用`Proxy.newProxyInstance()`方法创建代理对象,该方法会返回一个实现了指定接口的代理对象。
示例代码(Java):
```java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
private Object realObject;
public JDKProxy(Object realObject) {
this.realObject = realObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method call...");
Object result = method.invoke(realObject, args);
System.out.println("After method call...");
return result;
}
public static void main(String[] args) {
TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
JDKProxy jdkProxy = new JDKProxy(teacherDaoImpl);
TeacherDao proxy = (TeacherDao) Proxy.newProxyInstance(
teacherDaoImpl.getClass().getClassLoader(),
teacherDaoImpl.getClass().getInterfaces(),
jdkProxy);
proxy.teach();
}
}
```
动态代理(CGLIB代理)
定义接口:定义一个接口,代理类和真实对象都需要实现该接口。
创建代理对象:使用CGLIB库提供的`Enhancer`类来创建代理对象,该类会在运行时动态生成代理类的字节码。
示例代码(Java):