Java基础之代理模式

五段式S型算法笔记 又因为有 v-v0= 0.5jt通式: 所以有 vm-v0= 0.5jtm 所以有4vm-4v0= 2jtm。算法1: v=2vm-v0-0.5*jt+2jt*tm-2jtm*tm。加加速度j 自己设置 已知,vmax自己设置已知;所以有4vm-4v0= 2jtm带入算法1。 阅读详情

代理模式是常见的设计模式之一,意图在为指定对象提供一种代理以控制对这个对象的访问。Java中的代理分为动态代理和静态代理,动态代理在Java中的应用比较广泛,比如Spring的AOP实现、远程RPC调用等。静态代理和动态代理的最大区别就是代理类是JVM启动之前还是之后生成。本文会介绍Java的静态代理和动态代理,以及二者之间的对比,重点是介绍动态代理的原理及其实现。

代理模式

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

代理示例图

代理的组成

代理由以下三部分角色组成:

  • 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
  • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
  • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

代理的优点

  1. 职责清晰:真实的角色就是实现实际业务的逻辑,不用关系非业务的逻辑(如事务管理)。
  2. 隔离作用:代理对象可以在客户端和目标对象之间起到中介作用,目标对象不直接暴露给客户端,从而实现隔离目标对象的作用
  3. 高可扩展性:代理对象可以对目标对象进行灵活的扩展。

代理的例子

我们用一个加载并显示图片的例子来解释代理的工作原理,图片存在磁盘上,每次IO会花费比较多的事件,如果我们需要频繁的显示图片,每次都从磁盘读取会花费比较长的时间。我们通过一个代理来缓存图片,只有第一次读取图片的时候才从磁盘读取,之后都从缓存中读取,源码示例如下:

import java.util.*;
 
interface Image {
    public void displayImage();
}

//on System A 
class RealImage implements Image {
    private String filename;
    public RealImage(String filename) { 
        this.filename = filename;
        loadImageFromDisk();
    }

    private void loadImageFromDisk() {
        System.out.println("Loading   " + filename);
    }

    public void displayImage() { 
        System.out.println("Displaying " + filename); 
    }
}

//on System B 
class ProxyImage implements Image {
    private String filename;
    private Image image;
 
    public ProxyImage(String filename) { 
        this.filename = filename; 
    }
    public void displayImage() {
        if(image == null)
              image = new RealImage(filename);
        image.displayImage();
    }
}
 
class ProxyExample {
    public static void main(String[] args) {
        Image image1 = new ProxyImage("HiRes_10MB_Photo1");
        Image image2 = new ProxyImage("HiRes_10MB_Photo2");     
        
        image1.displayImage(); // loading necessary
        image2.displayImage(); // loading necessary
    }
}

静态代理

静态代理需要在程序中定义两个类:目标对象类和代理对象类,为了保证二者行为的一致性,目标对象和代理对象实现了相同的接口。代理类的信息在程序运行之前就已经确定,代理对象中会包含目标对象的引用。

举例说明静态代理的使用: 假设我们有一个接口方法用于计算员工工资,有一个实现类实现了具体的逻辑,如果我们需要给计算员工工资的逻辑添加日志应该怎么办呢?直接在计算工资的实现逻辑里面添加会导致引入非业务逻辑,不符合规范。这个时候我们就可以引入一个日志代理,在计算工资前后输出相关的日志信息。

  • 计算员工工资的接口定义如下:
public interface Employee {
    double calculateSalary(int id);
}
  • 计算员工工资的实现类如下:
public class EmployeeImpl {
    public double calculateSalary(int id){
        return 100;
    }
}
  • 带有日志的代理类的实现如下:
public class EmployeeLogProxy implements Employee {

    //代理类需要包含一个目标类的对象引用
    private EmployeeImpl employee;

    //并提供一个带参的构造方法用于指定代理哪个对象
    public EmployeeProxyImpl(EmployeeImpl employee){
        this.employee = employee;
    }

    public double calculateSalary(int id) {

        //在调用目标类的calculateSalary方法之前记录日志
        System.out.println("当前正在计算员工: " + id + "的税后工资");
        double salary = employee.calculateSalary(id);
        System.out.println("计算员工: " + id + "的税后工资结束");
        // 在调用目标类方法之后记录日志
        return salary;
    }
}

动态代理

动态代理的代理对象类在程序运行时被创建,而静态代理对象类则是在程序编译期就确定好的,这是二者最大的不同之处。动态代理的优势再于不需要开发者手工写很多代理类,比如上面的例子中,如果再来一个Manager类计算工资的逻辑需要日志,那么我们就需要新建一个ManagerLogProxy来代理对象,如果需要代理的对象很多,那么需要写的代理类也会很多。

而使用动态代理则没有这种问题,一种类型的代理只需要写一次,就可以适用于所有的代理对象。比如上文中的Employee和Manager,二者只需要抽象一个计算薪资相关的接口,就可以使用同一套动态代理逻辑实现代理。

动态代理示例

下面我们使用上文中的Employee和Manager计算薪资的逻辑来展示动态代理的用法。

接口的抽象

我们知道Employee和Manager都有计算薪资的逻辑,而且需要对计算薪资的逻辑进行日志记录,所以我们需要抽象一个计算薪资的接口:

public interface SalaryCalculator {
    double calculateSalary(int id);
}

接口的实现

public class EmployeeSalaryCalculator implements SalaryCalculator{
    public double calculateSalary(int id){
        return 100;
    }
}
public class ManagerSalaryCalculator implements SalaryCalculator{
    public double calculateSalary(int id){
        return 1000000;
    }
}

创建动态代理的InvocationHandler

public class SalaryLogProxy implements InvocationHandler {
    private SalaryCalculator calculator;

    public SalaryLogProxy(SalaryCalculator calculator) {
        this.calculator = calculator;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("--------------begin-------------");
        Object invoke = method.invoke(subject, args);
        System.out.println("--------------end-------------");
        return invoke;
    }
}

创建代理对象

public class Main {

    public static void main(String[] args) {
        SalaryCalculator calculator = new ManagerSalaryCalculator();
        InvocationHandler calculatorProxy = new SalaryLogProxy(subject);
        SalaryCalculator proxyInstance = (SalaryCalculator) Proxy.newProxyInstance(calculatorProxy.getClass().getClassLoader(), subject.getClass().getInterfaces(), calculatorProxy);
        proxyInstance.calculateSalary(1);
    }

}

动态代理源码分析

动态代理的流程如下图所示,可以看到动态代理中包含以下内容:

  • 目标对象:我们需要代理的对象,对应上文中的new ManagerSalaryCalculator()。
  • 接口:目标对象和代理对象需要共同提供的方法,对应上文中的SalaryCalculator。
  • Proxy代理:用于生成代理对象类。
  • 代理对象类:通过代理和对应的参数得到的代理对象。
  • 类加载器:用于加载代理对象类的类加载器,对应上文中的calculatorProxy.getClass().getClassLoader()。

动态代理流程

Proxy.newProxyInstance

动态代理的关键代码就是Proxy.newProxyInstance(classLoader, interfaces, handler).

  • 可以看到Proxy.newProxyInstance一共做了两件事情:1.获取代理对象类的构造函数,2:根据构造函数实例化代理对象。
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
                Class<?>[] interfaces, InvocationHandler h) {
    Objects.requireNonNull(h);

    final Class<?> caller = System.getSecurityManager() == null
                                    ? null : Reflection.getCallerClass();

    /*
     * Look up or generate the designated proxy class and its constructor.
     */
    // 获取代理对象类的构造函数,里面就包含了代理对象类的构建和加载
    Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
 
    // 根据构造函数生成代理实例.
    return newProxyInstance(caller, cons, h);
}

代理对象类

通过查看源码,我们可以发现代理对象类都extend了Proxy类并实现了指定接口中的方法。由于java不能多继承,这里已经继承了Proxy类了,不能再继承其他的类。所以JDK的动态代理不支持对实现类的代理,只支持接口的代理。

编译zlib库给IOS平台用 在弹出的下面对话框中选择Unix Makefiles ,然后点击(Done)完成。使用 lipo与otool查看库类型为arm64,现在可在ios平台使用该库了。zlib自带CMakeLists.txt 所以用CMake-GUI来生成。修改为与系统当前安装的cmake版本 (如:3.22.1)选择zlib源码目录及输出目录,输入下图的CMAKE参数。点击Configure,在弹出的对话框中选择Yes。cmake --install . 进行安装。cmake --build . 进行编译。 阅读详情

相关推荐

WorkBuddy实战技巧:搭建高效AI工作台与自动化流程

在数字化办公场景中,AI工作台正逐渐成为提升个人与团队效率的关键工具。它不同于简单的聊天机器人,而是通过集成技能包(Skill)、自动化触发与文档处理能力,把重复性任务如信息提取、周报生成、数据表格整理等变为标准化流程。其核心原理在于将用户需求拆解为可执行的指令链,并借助本地脚本、API调用及定时任务实现“对话即操作”的智能协作。这种技术价值不仅适用于程序员,更惠及运营、客服、行政、科研等日常与文字数据打交道的群体。从自动签到、会议纪要,到批量处理Excel与合同要点提取,AI工作台的应用场景已覆盖多个高频

weixin_42547431的博客 333

Java代理之代理模式

Java代理之设计模式1 概述 代理模式(Proxy Pattern)是结构型设计模式中的一种,它通常为其他对象提供一种代理机制以增强和控制对该对象的访问,但不改变原来的对象本身的结构。代理一般可以作为与对象交互的接口,这些对象包括:网络连接对象、远程对象、创建一次需要很大开销的对象、需要保护的对象、内存中的大对象、需要附加线程安全的对象、需要在原来的功能上附加或扩展的对象等等。2 实

时光烙 758

Python读取三菱PLC数据

3、支持自定义的数据读写操作。直接调用Read方法,可以读取到原生的byte数组,然后进行组合数据。1、每次的数据交互您都可以判断是否成功,如果您不判断,如果网络断开或是异常,会影响程序的执行。Qna3E协议的ascii类 MelsecMcAsciiNet。A兼容1E协议的二进制类 MelsecA1ENet。Qna3E协议的二进制类 MelsecMcNet。2、读写操作支持单个数和数组。

weixin_46744807的博客 1998

Java代理类详解

从以下几个方面浅谈一下java的代理机制。如有不足,欢迎留言交流。 为什么使用代理 类比一: 假如你刚毕业,要租一个房子,有两种方式。一种就是自己去找房源,找房东,这样无疑时间成本是很高的。第二种方式就是找一个房产中介,你只需要提供你的需求和租房的规格和条件。中介就会推荐你心仪的房子。这里的中介就是代理人,房源就是目标对象,你可以直接找房源,也可以通过中介找房源。 类比二: 记者要采访一个儿童。...

weixin_43469379的博客 3034

【CubeMX】STM32G474 HRTIM 互补PWM与死区时间配置实战

本文详细介绍了如何使用STM32CubeMX配置STM32G474的高分辨率定时器HRTIM生成互补PWM波形并精确设置死区时间。通过实战步骤讲解时钟配置、死区计算与高级功能,帮助工程师在电机驱动和电源应用中实现精准控制,避免上下桥臂直通风险。

grpc6streamer的博客 727

Ruoyi-Cloud-Plus新手必看:Gateway启动失败的两种解决方案(Nacos配置空间问题)

本文详细解析了Ruoyi-Cloud-Plus框架中Gateway启动失败的常见原因及解决方案,重点围绕Nacos配置空间问题展开。针对新手开发者,提供了两种实用方案:快速切换到public空间或规范创建dev空间并迁移配置,帮助开发者高效解决网关启动故障,确保微服务项目顺利运行。

weixin_30872499的博客 492

(Java笔记)静态代理

代理模式是在不修改目标对象(被代理对象)的基础上,通过代理对象(扩展代理类),进行一些功能的附加与增强——>静态代理是在不改变源代码的基础上增加新的功能。

张松的博客 5436

基于java实现的弹幕视频网站

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示弹幕视频网站,在弹幕视频网站可以查看首页、视频信息、商品信息、论坛信息、我的、跳转到后台、购物车、客服等内容前台首页界面图登录,通过登录填写账号、密码等信息进行登录操作登录界面图视频信息界面图。

DC5621的博客 1333

java框架中的controller层、dao层、domain层、service层、view层

                                       1.Controller层:接口层,用户访问请求时对接。     Controller层负责具体的业务模块流程的控制,在此...

TwcatL 3266

让 Claude Code 接管 SAP 事务流, 用 Python 和 SAP GUI Scripting 做一个真正能干活的 AI Agent

摘要:SAP系统自动化面临的核心瓶颈在于繁琐的GUI操作而非分析能力不足。通过整合Claude AI、Python和SAP GUI Scripting技术,可构建能直接操作SAP界面的智能代理。该方案利用SAP官方提供的脚本接口,实现事务码执行、界面导航、数据提取等自动化操作,特别适用于DMLT过账引擎等复杂错误分析场景。相比传统SQL导出方案,这种GUI级自动化能处理树控件、ALV表格等复杂界面元素,且无需额外API开发,直接在现有SAP GUI会话上工作,在保持原有权限体系的同时显著提升效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 321

YOLOv11改进策略【Neck】| ASF-YOLO 注意力尺度序列融合模块改进颈部网络,提高小目标检测精度

ASF-YOLO是一种基于YOLO的新颖框架,结合了空间和尺度特征以实现准确和快速的分割。其中,注意力尺度序列融合模块。

Limiiiing的博客 4391

Java基础——代理模式

代理模式是一种比较好理解的设计模式。简单来说就是。

2403_87486006的博客 1407

重回童年的经典系列☀️| 【坦克大战3D版】游戏制作+解析

带你重回童年的经典系列——坦克大战3D版制作,感兴趣的可以看看呀~

努力前行,总会成为自己心中的那道光 5万+

【Java基础】代理模式

代理模式就是我们用一个替代的对象来对真实的对象进行访问,并且对这个对象进行一些额外扩展功能。灵活性:静态代理灵活性差,接口增加了新的方法以后,目标对象和代理对象都需要进行修改,而且,对目标代码的每个类都要进行代理。动态代理则灵活一些,不需要对每个目标类都实现代理。JVM角度:静态代理在编译时就对接口,实现类,代理类生成了class文件。动态代理则是在运行时生成类字节码,并加载到JVM中。

weixin_57597001的博客 416

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入理解 Java 代理模式:从基础到实战​

代理模式是Java开发中常用的结构型设计模式,通过在客户端和真实对象之间引入代理对象来控制访问,实现功能的扩展和优化。代理模式分为静态代理和动态代理,动态代理又包括JDK动态代理和CGLIB动态代理。静态代理在编译时确定代理类,实现简单但灵活性差;动态代理在运行时生成代理类,JDK动态代理基于接口,CGLIB动态代理基于子类,适用于不同场景。代理模式广泛应用于远程代理、虚拟代理、保护代理等场景,能够解耦代码、扩展功能、控制访问,但也增加了系统复杂度和性能开销。掌握代理模式有助于提高代码的可维护性和扩展性。

qq_20294455的博客 1519

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

JAVA安全基础之代理模式(一)

JAVA安全基础之代理模式(一) 代理模式是java的一种很常用的设计模式,理解代理模式,在我们进行java代码审计时候是非常有帮助的。 静态代理 代理,或者称为 Proxy ,简单理解就是事情我不用去做,由其他人来替我完成。在黄勇《架构探险》一书中,我觉得很有意思的一句相关介绍是这么说的: 赚钱方面,我就是我老婆的代理;带小孩方面,我老婆就是我的代理;家务事方面,没有代理。 代理类与被代理...

洋洋的小黑屋 199

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

proxy-代理模式-Java基础

在 Java 动态代理机制中接口和Proxy类是核心。Proxy,这个方法主要用来生成一个代理对象。Class<?......loader:类加载器,用于加载代理对象。interfaces: 被代理类实现的一些接口;h: 实现了接口的对象;要实现动态代理的话,还必须需要实现来自定义处理逻辑。当我们的动态代理对象调用一个方法时,这个方法的调用就会被转发到实现接口类的invoke方法来调用。/*** 当你使用代理对象调用方法的时候实际会调用到这个方法*/invoke()proxy。

阿里渣渣java研发组-群主 1576

Java基础 代理模式

代理是一个多义词,它常出现在我们的生活中:比如品牌代理、货运代理、代理商等。代理就是起到了中介的作用,而我今天要说的代理,它是一种计算机技术的术语。 代理模式角色划分 目标对象:target object 代理对象:proxy object 静态代理 场景: 需要给一个功能添加日志,但没有源码 继承 聚合(基于接口) 动态代理 ...

TBryant的博客 245

java基础之代理模式[29]

java基础之代理模式[29]

FlymaAqi,芜湖,飞马阿起,passion!passion! 127

java基础之代理模式

一、中介隔离作用     代理模式,第一次接触它,是在学习.Net的时候看的一本书,叫做《大话设计模式》,至今已快三年了。相信看过这本书的同学们,都记得书中的代理模式,就是为他人做嫁衣裳的故事。好,我们回归代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是代理类与委托...

weixin_37705192的博客 186

java基础——代理模式

使用场景: 保护目标对象 增强目标对象 降低系统的耦合度 易于扩展 特点: 实现方式: 静态代理 动态代理:jdk动态代理、cglib动态代理 jdk动态代理 cglib动态代理 ...

weixin_41090378的博客 135

java基础-代理模式

java代理模式? 设计模式的分类 25种 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模...

weixin_30642029的博客 105
上一篇: Nginx 挂了怎么办?怎么实现高可用?
下一篇: 密码学系列之:bcrypt加密算法详解
在酒吧写代码
博客等级 码龄7年 210粉丝 330原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值