1.什么是代理模式
代理模式是指为其他对象提供一种代理,以控制对这个对象的访问。代理对象在访问对象和目标对象之间起到中介作用。最简单的代理就是我们现实生活中的中介,比如房产中介。他们代理的不同的房主出售他们的房子,从中抽取佣金赚钱的方式
Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。
代理(Proxy)模式分为三种角色:
抽象角色(Subject): 通过接口或抽象类声明真实角色和代理对象实现的业务方法。
真实角色(Real Subject): 实现了抽象角色中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
代理角色(Proxy) : 提供了与真实角色相同的接口,其内部含有对真实角色的引用,它可以访问、控制或扩展真实角色的功能
2.静态代理
静态代理需要手动创建一个代理类,该代理类与原始类实现相同的接口,代理类中持有一个原始类的引用,并在代理类的方法中调用原始类的对应方法。在这个过程中,我们可以在原始类的方法调用前后添加一些额外的操作。以下是一个简单的静态代理示例:
package cn.lyf.callback.test;
import org.junit.Test;
public class DemoTest {
/**
* 设置一个接口
*/
public interface Image {
void display();
}
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk();
}
@Override
public void display() {
System.out.println("销毁图片 " + fileName);
}
private void loadFromDisk() {
System.out.println("加载图片 " + fileName);
}
}
public class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName);
}
realImage.display();
}
}
@Test
public void test(){
Image image = new ProxyImage("test.jpg");
image.display();
}
}
运行得到结果
image.png
3.动态代理
动态代理是一种更加灵活的代理模式,它不需要手动创建代理类,而是在运行时动态地生成代理对象。Java中动态代理是通过反射机制实现的,它允许我们在运行时创建一个代理对象,并将方法调用转发到原始对象上。动态代理通常需要实现一个InvocationHandler接口,该接口中有一个invoke方法,用于处理方法调用。
我们还是引用上面的图片类来示例
package cn.lyf.callback.test;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Demo1Test {
public interface Image {
void display();
}
public class ImageImpl implements Image {
@Override
public void display() {
System.out.println("销毁照片!");
}
}
public class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method " + method.getName());
return result;
}
}
@Test
public void test(){
Image image = new ImageImpl();
InvocationHandler handler = new LogHandler(image);
Image proxyHello = (Image) Proxy.newProxyInstance(
image.getClass().getClassLoader(),
image.getClass().getInterfaces(),
handler
);
proxyHello.display();
}
}
运行结果
image.png
网友评论