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();

}

}

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

相关推荐
kk哥889912 分钟前
C++ 对象 核心介绍
java·jvm·c++
招风的黑耳22 分钟前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
xunyan623423 分钟前
面向对象(下)-接口的理解
java·开发语言
程序员游老板26 分钟前
基于SpringBoot3+vue3的爱心陪诊平台
java·spring boot·毕业设计·软件工程·课程设计·信息与通信
期待のcode29 分钟前
Springboot核心构建插件
java·spring boot·后端
遥不可及~~斌31 分钟前
Java 面试题集 -- 001
java·开发语言
C182981825751 小时前
HttpURLConnection 与其他客户端关系
java
通往曙光的路上1 小时前
发邮件1、创建邮箱
java
麦麦鸡腿堡2 小时前
Java_类的加载
java·开发语言
JIngJaneIL2 小时前
基于java + vue校园快递物流管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js