首页 > 编程语言 >Java代理模式详解

Java代理模式详解

时间:2024-07-30 11:00:38浏览次数:10  
标签:Java target Object request 代理 详解 RealSubject public

Java代理模式详解

概念

代理模式是一种设计模式,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。在Java中,代理模式主要分为静态代理和动态代理。

静态代理

静态代理是在编译时就已经确定好代理类要代理谁。在静态代理中,我们创建一个代理类来实现与目标对象相同的接口,并在代理类中维护一个目标对象的引用。当客户端调用代理类的方法时,实际上是通过代理类间接地调用目标对象的方法。

示例

假设我们有一个接口Subject和一个实现类RealSubject

public interface Subject {
    void request();
}

public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

接下来,我们创建一个代理类ProxySubject,它实现了Subject接口并持有一个RealSubject的实例:

public class ProxySubject implements Subject {
    private RealSubject realSubject;
    
    public ProxySubject() {
        this.realSubject = new RealSubject();
    }
    
    @Override
    public void request() {
        preRequest();
        realSubject.request();
        postRequest();
    }
    
    private void preRequest() {
        System.out.println("ProxySubject: Preparing request.");
    }
    
    private void postRequest() {
        System.out.println("ProxySubject: Request completed.");
    }
}

ProxySubject中,我们在调用realSubject.request()之前和之后分别执行了一些额外的操作。这就是静态代理的一个典型用法:在目标方法执行前后插入额外的逻辑。

动态代理

动态代理与静态代理的主要区别在于,动态代理是在运行时动态地生成代理类。在Java中,我们可以通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现动态代理。

示例

首先,我们定义一个InvocationHandler的实现:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyHandler implements InvocationHandler {
    private Object target;
    
    public DynamicProxyHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        preRequest();
        Object result = method.invoke(target, args);
        postRequest();
        return result;
    }
    
    private void preRequest() {
        System.out.println("DynamicProxyHandler: Preparing request.");
    }
    
    private void postRequest() {
        System.out.println("DynamicProxyHandler: Request completed.");
    }
    
    public static Object newInstance(Object target) {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new DynamicProxyHandler(target)
        );
    }
}

然后,我们可以这样使用动态代理:

Subject realSubject = new RealSubject();
Subject proxySubject = (Subject) DynamicProxyHandler.newInstance(realSubject);
proxySubject.request();

这段代码首先创建了一个RealSubject实例,然后通过DynamicProxyHandler.newInstance()方法创建了一个代理对象。当我们调用proxySubject.request()时,实际上会调用DynamicProxyHandler中的invoke()方法,从而实现在目标方法执行前后插入额外的逻辑。

总结

代理模式在Java中主要有两种实现方式:静态代理和动态代理。静态代理在编译时就已经确定好代理类要代理谁,而动态代理则可以在运行时动态地生成代理类。这两种方式都可以实现在目标方法执行前后插入额外的逻辑,但动态代理更加灵活和强大。

标签:Java,target,Object,request,代理,详解,RealSubject,public
From: https://blog.csdn.net/2401_83447580/article/details/140757148

相关文章

  • 基于java+ssm+jsp旅游论坛设计与实现+vue录像(源码+lw+部署文档+讲解等)
    前言......
  • 基于java+ssm+jsp旅行社管理系统的设计与实现录像(源码+lw+部署文档+讲解等)
    前言......
  • 机器学习:详解是否要使用端到端的深度学习?(Whether to use end-to-end learning?)
    详解是否要使用端到端的深度学习?假设正在搭建一个机器学习系统,要决定是否使用端对端方法,来看看端到端深度学习的一些优缺点,这样就可以根据一些准则,判断的应用程序是否有希望使用端到端方法。这里是应用端到端学习的一些好处,首先端到端学习真的只是让数据说话。所以如果有足够多......
  • 初识Java多线程
    Java中如何创建新线程?第一种方式:继承Thread类写一个子类继承Thread重写run方法创建该类的对象,代表一个线程调用start方法启动线程,该线程会执行run方法这种方式的优点在于编码方式简单,但是该类已经继承了Thread类,不能继承其他类。注意:启动线程时一定调用start方法,而非ru......
  • 黑马Java零基础视频教程精华部分_9_面向对象进阶(1)
    系列文章目录文章目录系列文章目录一、static(表示静态)是Java中的一个修饰符,可以修饰成员方法,成员变量1、静态变量2、静态变量底层原理3、static静态方法4、工具类、测试类、Javabean类5、static注意事项从代码层面从内存层面6、重新认识main方法一、static(表......
  • Dom-API | MutationObserver使用方法详解
    MutationObserver介绍MutationObserver是是一个用于监视DOM变动的WebAPI。通过它可以监控DOM树中的更改,比如元素的属性、子元素的增加和删除等,并在这些变化发生时执行回调函数。可以替代过时的MutationEvents,它具有更高的性能和更广的适用性。使用步骤详细说明1.创......
  • 两种常见排序(冒泡排序和选择排序)详解
    一、冒泡排序1.1、冒泡排序的原理讲解。例如有以下7个数的无序数列储存在数组arr[7]中,现在需要用冒泡排序法来对以下序列进行排序冒泡排序是比较相邻的两个数,如果第一个数比第二个数大,这两个数就要交换两个数的位置,如果第一个数小于第二个数则不用变换位置,例如第一个数3比......
  • [Java基础]String 为什么是不可变的?
    关于这个问题,网上有人说,是因为String类被写成final或者String中的成员变量value数组被写成final,但其实并不是,下面做一个实验publicfinalclassMyString{publicfinalchar[]value={'z'};}首先我们定义了一个类Mystring,并且类和成员变量都被设置成finalpublicclas......
  • Java编写:给 20 块钱买可乐,每瓶可乐 3 块钱,喝完之后退瓶子可以换回 1 块钱, 问最多可以
    代码如下:注意while和count一般连用,如果是i只会循环执行一次!importjava.util.Scanner;publicclasstest16{publicstaticvoidmain(String[]args){//给20块钱买可乐,每瓶可乐3块钱,喝完之后退瓶子可以换回1块钱,问最多可以喝到多少瓶可乐//......
  • JavaEE 初阶(11)——多线程9之“阻塞队列”
    目录一.什么是“阻塞队列”二.生产者消费者模型2.1概念2.2 组件 2.3实际应用2.4优点 a.实现“解耦合” b.流量控制——“削峰填谷”2.5代价a. 更多的机器b.通信时间延长三.阻塞队列的实现 3.1简述  3.2ArrayBlockingQueue的使用3.3实现MyA......