Java设计模式之代理模式

代理模式是 Java 中常用的设计模式之一,它通过引入一个代理对象来控制对实际对象的访问,从而实现对目标对象的间接访问和控制。代理模式可以用于多种场景,比如权限控制、延迟加载、日志记录等。

在 Java 中,代理模式通常分为静态代理和动态代理两种实现方式。下面分别介绍这两种代理模式的实现。

  1. 静态代理

静态代理是在编译时就已经确定代理类和目标类的关系,代理类是手动编写的。静态代理需要为每一个需要代理的类编写一个代理类,这样会导致代码冗余。以下是静态代理的一个简单示例:

```java

// 定义接口

public interface Image {

void display();

}

// 目标类

public class RealImage implements Image {

private String filename;

public RealImage(String filename) {

this.filename = filename;

loadImageFromDisk();

}

private void loadImageFromDisk() {

System.out.println("Loading " + filename);

}

@Override

public void display() {

System.out.println("Displaying " + filename);

}

}

// 代理类

public class ImageProxy implements Image {

private RealImage realImage;

private String filename;

public ImageProxy(String filename) {

this.filename = filename;

}

@Override

public void display() {

if (realImage == null) {

realImage = new RealImage(filename);

}

realImage.display();

}

}

// 使用示例

public class Main {

public static void main(String[] args) {

Image image = new ImageProxy("test.jpg");

// 图片加载和显示都由代理类处理

image.display();

}

}

```

  1. 动态代理

动态代理是在运行时动态生成代理类,无需手动编写代理类。Java 中的动态代理主要基于两个类:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。以下是动态代理的一个简单示例:

```java

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

// 定义接口

interface Image {

void display();

}

// 目标类

class RealImage implements Image {

private String filename;

public RealImage(String filename) {

this.filename = filename;

loadImageFromDisk();

}

private void loadImageFromDisk() {

System.out.println("Loading " + filename);

}

@Override

public void display() {

System.out.println("Displaying " + filename);

}

}

// InvocationHandler 实现类

class ImageInvocationHandler implements InvocationHandler {

private Object target;

public ImageInvocationHandler(Object target) {

this.target = target;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("Before method execution");

Object result = method.invoke(target, args);

System.out.println("After method execution");

return result;

}

}

// 使用示例

public class Main {

public static void main(String[] args) {

Image realImage = new RealImage("test.jpg");

Image proxyImage = (Image) Proxy.newProxyInstance(

Image.class.getClassLoader(),

new Class[]{Image.class},

new ImageInvocationHandler(realImage)

);

// 图片加载和显示由代理类处理,并且在方法执行前后添加了额外逻辑

proxyImage.display();

}

}

无论是静态代理还是动态代理,都能够实现对目标对象的代理和控制,根据具体的需求选择合适的代理模式。动态代理相比静态代理更加灵活,但是也需要理解其背后的原理和实现机制。

相关推荐
程序员岳焱3 分钟前
Java 高级泛型实战:8 个场景化编程技巧
java·后端·编程语言
钢铁男儿12 分钟前
C# 类和继承(扩展方法)
java·servlet·c#
饮长安千年月19 分钟前
JavaSec-SpringBoot框架
java·spring boot·后端·计算机网络·安全·web安全·网络安全
移动开发者1号20 分钟前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
代码匠心20 分钟前
从零开始学Flink:揭开实时计算的神秘面纱
java·大数据·后端·flink
jie1889457586635 分钟前
C++ 中的 const 知识点详解,c++和c语言区别
java·c语言·c++
网安INF41 分钟前
RSA加密算法:非对称密码学的基石
java·开发语言·密码学
蔡蓝1 小时前
设计模式-观察着模式
java·开发语言·设计模式
异常君1 小时前
@Bean 在@Configuration 中和普通类中的本质区别
java·spring·面试
jackson凌1 小时前
【Java学习笔记】Math方法
java·笔记·学习