代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。
代理模式又分为静态代理和动态代理:
- 静态代理:静态代理的代理类在编译器就生成。
- 动态代理:动态代理的代理类在java运行时动态生成。
步骤一:创建一个接口
public interface Image {
void display();
}
步骤 2:创建实现接口的实体类。
public DisplayImage(String fileName){
@Override
public void display() {
System.out.println("图片显示");
}
}
public class ProxyDisplayImage implements Image{
private DisplayImage displayImage;
@Override
public void display() {
if(displayImage == null){
displayImage = new DisplayImage();
}
System.out.println("代理-图片显示");
displayImage.display();
}
}
步骤 3
当被请求时,使用 ProxyDisplayImage 来获取 DisplayImage 类的对象。
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyDisplayImage();
image.display();
}
}
步骤4
执行程序,输出结果:
代理-图片显示 图片显示动态代理
图片显示接口:
public interface Image {
void display();
}
接口的显示类
public DisplayImage(String fileName){
@Override
public void display() {
System.out.println("图片显示");
}
}
代理工厂类(通过此类获取代理对象):
public class ProxyFactory {
private DisplayImage displayImage = new DisplayImage();
public Image getProxyObj(){
Image image = (Image)Proxy.newProxyInstance(
displayImage.getClass().getClassLoader(),
displayImage.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理-图片显示");
Object result = method.invoke(displayImage,args);
return result;
}
}
);
return image;
}
}
在Proxy.newProxyInstance()中有三个参数:
- ClassLoader loader(类加载器):加载代理类,通过目标对象获取。
- Class>[] interfaces:代理类实现的接口的字节码对象。
- InvocationHandler h:代理对象的处理程序。
至此动态代理模式就完成了,其中通过ProxyFactory中的方法getProxyObj()中的Proxy.newProxyInstance动态获取了代理类。
代理模式在客户端和目标对象之前起到了一个中介和保护目标对象的作用,而且还可以扩展目标对象的功能,并使客户端和目标对象分离,降低了耦合性,但是缺点就是增加了程序的复杂度。



