设计模式 -(11)动态代理(Dynamic Proxy)

Java Dynamic Proxy And Aspect Application (二) 动态代理和 Spring AOP 12 种切点定义方式 ProxyFactory ProxyFactoryBean AspectJProxyFactory 阅读详情

设计模式 -(11)动态代理(Dynamic Proxy)

动态代理是 静态代理 的升级,通过静态代理我们可以对某一个接口的功能进行扩展,而动态代理可以对任意接口进行扩展

如何使用JDK动态代理

如下是使用JDK动态代理对 Programmer 对象生成代理对象的过程,具体通过 java.lang.reflect.Proxy 类生成代理类

package com.example.dp._11dynamicproxy;

import com.example.dp._10staticproxy._02.Programme;
import com.example.dp._10staticproxy._02.Programmer;

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


public class ProgrammerTimeHandler implements InvocationHandler {

    /**
     * 被代理的对象
     */
    private Object target;

    public ProgrammerTimeHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        long start = System.currentTimeMillis();
        result = method.invoke(target,args);
        System.out.println("方法耗时:" + (System.currentTimeMillis() - start));
        return result;
    }

    public static void main(String[] args) {
        // 被代理的对象
        Programme target = new Programmer();
        // 被代理对象功能扩展类
        ProgrammerTimeHandler programmerTimeHandler = new ProgrammerTimeHandler(target);
        // 生成的代理对象
        Programme programmerTimeProxy =
                (Programme) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), programmerTimeHandler);
        programmerTimeProxy.action();
    }
}

通过以上方式可以生成任意类的代理对象,在静态代理统计时长的例子中只能对 Programme 这一个类型的方法进行时长统计,并且如果要对接口中的多个方法进行同一个操作可能会产生重复代码,而动态代理通过反射方式可以对接口的任意方法进行时长统计,没有额外的代码产生

如何查看JDK生成的动态代理对象

查看源码 java.lang.reflect.Proxy.ProxyClassFactory 类 中的 apply 方法,其中下面这一段为生成代理类 .class 文件的代码:

/*
 * Generate the specified proxy class.
 */
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces, accessFlags);

sun.misc.ProxyGenerator.generateProxyClass 方法:
其中 saveGeneratedFiles 参数控制是否显示地保存 .class 文件

public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
    ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
    final byte[] var4 = var3.generateClassFile();
    if (saveGeneratedFiles) {
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                try {
                    int var1 = var0.lastIndexOf(46);
                    Path var2;
                    if (var1 > 0) {
                        Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                        Files.createDirectories(var3);
                        var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                    } else {
                        var2 = Paths.get(var0 + ".class");
                    }

                    Files.write(var2, var4, new OpenOption[0]);
                    return null;
                } catch (IOException var4x) {
                    throw new InternalError("I/O exception saving generated file: " + var4x);
                }
            }
        });
    }

    return var4;
}

saveGeneratedFiles 内容如下 如下:

private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));

由此可知将这个系统参数设置为 true 既可以显示地保存 .class 文件,否则.class文件只会加载到内存中,

System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

再次运行,在工程目录下会生成 com/sun/proxy 文件夹,代理类 .class 文件存放于此:

通过JDK动态代理生成的 .class 文件内容

可见 代理对象 $Proxy0 实现了 Programme 接口,在 action 方法中调用了父类 Proxy 属性 InvocationHandler h 的 invoke 方法,而 这个 InvocationHandler 就是我们调用 Proxy.newProxyInstance 时传入的,由如下代码可以看出生成的代理对象实际上是调用 $Proxy0(InvocationHandler var1) 构造方法实例化了 $Proxy0

return cons.newInstance(new Object[]{h});
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sun.proxy;

import com.example.dp._10staticproxy._02.Programme;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Programme {
    private static Method m1;
    private static Method m2;
    private static Method m0;
    private static Method m3;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void action() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m3 = Class.forName("com.example.dp._10staticproxy._02.Programme").getMethod("action");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

vue3接入大华摄像头 ┃ ┃ ┣ 📜PlaybackModal.vue 回放列表模态框。┃ ┃ ┗ 📜VideoGrid.vue 视频播放区域。┃ ┃ ┣ 📜ControlPanel.vue 控制面板。┃ ┃ ┣ 📜DeviceList.vue 设备列表。┃ ┣ 📂module //大华摄像头文件。 阅读详情

相关推荐

相位相关匹配法的opencv C++实现

这一段就是PCIAM算法的核心了,计算两幅图像的峰值相关矩阵,也是完全按照matlab移植过来的,但是后面几行,是为了筛选一些不可能存在的情况,比如边缘处的完全重合,或者只有一行,或者一列重合等等情况,由于PCIAM算法在边缘处的响应值高,所以在一些场景下可能是一种干扰,所以进行了剔除,当然可以不剔除,就是对后期的峰值选取会有影响。头文件,以及各类函数,还有主函数,第一次独立的写这种分文件类型的项目,写的拉跨还请包涵,以及当然可以转成类的形式,但感觉有点小麻烦,后期再修改吧。

qq_43616651的博客 4260

填坑之动态代理生成的代理类文件在哪?

获取动态代理生成的代理类文件、Mybatis、设计模式

u010088278的博客 2951

HTPA 32x32d热成像传感器实战指南:从替代MLX90640到精准测温

本文为HTPA 32x32d热成像传感器提供了从硬件连接到精准测温的完整实战指南。针对MLX90640替代需求,详细解析了HTPA传感器的核心优势、IIC通信要点、EEPROM校准数据读取与解析、独特的块数据读取模式,并逐步拆解了五大温度补偿计算流程,旨在帮助开发者克服高开发门槛,实现稳定可靠的非接触式测温应用。

weixin_29279101的博客 312

Java动态代理(dynamic proxy)

代理模式通过代理对象拦截目标对象的访问,实现访问控制和功能增强。静态代理需实现相同接口并持有目标对象,动态代理则利用Java的Proxy和InvocationHandler在运行时生成代理类。

huangpf_vcx 605

Aruba无线控制器实战:如何用Client Match优化企业办公区漫游(附SNR调优技巧)

本文深入解析了如何利用Aruba无线控制器的Client Match功能优化企业办公区无线漫游体验。通过实战配置,详细阐述了基于SNR(信噪比)的精细化调优策略,包括阈值设定、负载均衡与场景化参数调整,旨在解决终端粘滞、乒乓漫游等问题,实现智能、平滑的无缝漫游。

weixin_28318011的博客 224

为R720安装iDRAC Service Module

这玩意找了好久资料, 教程都不咋靠谱, 要不就是有不理解的地方 所以直接一路莽着过河: 去官网找到设备对应的驱动程序: 几个查找筛选项看图 官网链接: https://www.dell.com/support/home/zh-cn/product-support/product/poweredge-r720/drivers 在下方的列表中找到对应系统版本的驱动并下载: 由于安装的系统为ESXi 6.5 U2 Dell定制版, 这里没有刚好的驱动, 所以下了个兼容的: 下载好后是一个压缩包:

Janus 6361

查看Proxy产生的代理对象

package com.demo; import java.io.FileOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import sun.misc.ProxyGenerator; public class DynamicPro

孔繁玉的专栏 1421

STM32CubeMX最新版下载安装全攻略(附官网访问问题解决方案)

本文提供了STM32CubeMX最新版的详细下载与安装指南,并针对国内开发者常见的官网访问缓慢、注册验证邮件延迟等问题,给出了实用的解决方案和备选策略。通过清晰的步骤解析,帮助用户快速部署这一强大的STM32图形化配置工具,从而高效启动嵌入式开发项目。

weixin_28256233的博客 193

对动态代理(DynamicProxy)的理解

1、动态代理属于AOP(面向切面编程)的一种思想。 2、代理对象和被代理对象都实现了相同接口。 3、动态代理是指系统根据要代理的接口,自动帮我们生成并编译代理类(实现了要代理接口),并将代理类中的代理逻辑抽象到 InvocationHandler 中,由开发者实现。静态代理中,我们需要自己实现代理类,将代理逻辑也写在代理类里面。而动态代理省去了我们自己写代理类的工作,系统只需要知道要代理的接口,然...

ganduwei的博客 1862

Abaqus滞回问题求解—浆锚连接装配式剪力墙滞回模拟

当下土木工程研究生,多数都在从事装配式混凝土构件安全或装配式混凝土构件连接节点力学性能的研究。研究这类问题,几乎脱离不开对有限元软件的使用,Abaqus求解能力非常强大,但模型处理能力相对较弱。装配式混凝土结构的有限元计算与传统现浇结构相比,其节点处理起来相对复杂,计算结果往往需要凸显出连接节点力学特性,所以对建模精程度的要求较高。所以向大家介绍一款工具—HyperMesh软件(一下简称Hm),它是专业的有限元前处理工具,用于处理装配式混凝土构件或连接节点有限元模型比较合适。这篇文章主要介绍如何利用Hm处理

qq_31918049的博客 2901

学Simulink——基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计仿真

本文介绍了一种基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计方法,通过Simulink建模实现。文章首先阐述了EKF在估计电机转子温度中的优势,即利用易测量信号(如电流、电压、转速)在线估计难以直接测量的转子温度,并分析了温升对电机性能的影响。随后详细讲解了电机热电增广模型的构建,包括定子电阻温度关系、一阶热近似模型和PMSM的dq轴方程。接着,文章提供了Simulink建模的详细步骤,包括PMSM+FOC电流环的搭建、EKF算法的实现(推荐使用ExtendedKalmanFilter块或MAT

xiaoheshang_123的博客 55

Java设计模式——代理模式,静态代理和动态代理

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问。 静态代理:静态定义代理类 动态代理:动态生成代理类,JDK自带的动态代理,需要反射的知识 1、静态代理 1.1:创建服务类接口 public interface...

海边小男孩的博客 222

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

动态代理Dynamic Proxy

  代理模式是常用的Java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类 预处理消息,过滤消息,把消息转发给委托类,以及事后处理消息等。   代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身 并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定服务。 动态代理类的字节码在程序运行时由Java反射机...

weixin_30852419的博客 92

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Dynamic Proxy (动态代理模式)

动态代理(运行期行为)主要有一个 Proxy类 和一个 InvocationHandler接口 动态代理角色: 1. 抽象主题角色 2. 真实主题角色(实现了抽象主题接口) 3. 动态代理主题角色(实现了 InvocationHandler接口,并实现了 invoke()方法) Proxy 要调用 newProxyInstance方法 代码演示: 1.抽象主题角色 Sub...

weixin_30734435的博客 84

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Dynamic Proxy : 动态代理

转载 http://www.zeroport.netSummary这篇文章介绍了Castle的动态代理是如何实现 AOP 的。 向来我是“拿来主义”,即只管拿来用,不管正在用的东西是怎么实现的。最近由于一直想把 AOP 以及 Io C 等技术加入到项目中,因此对这些技术相当关注。后来选择了CastleProject中的DynamicProxy作为关注对象。不过这次起了贪心,不想再只知道使...

weixin_33882443的博客 129

Java Dynamic Proxy

Reprint:http://java.dzone.com/articles/power-proxies-java In this article, I’ll show you the path that leads to true Java power, the use of proxies. They are everywhere but only a handful

Pandoras Box 1748

基于Dynamic Proxy技术的方法AOP拦截器开发

在面向对象编程中,会用到大量的类,并且会多次调用类中的方法。有时可能需要对这些方法的调用进行一些控制。如在权限管理中,一些用户没有执行某些方法的权限。又如在日志系统中,在某个方法执行完后,将其执行的结果记录在日志中。处理这些需求的一般做法是在调用这些方法的地方加上适当的代码。如以下C#代码如示: 1 public class Class1 2 { 3 public vo...

weixin_30337251的博客 148

dynamic proxy and class loader

http://www.chinaitpower.com/A200507/2005-07-27/170362.html对代理模式与Java动态代理类的理解 Understanding JBosshttp://www.lesun.org/html/2002-08/9175.htm Dynamic Proxy 在 Java RMI 中的应用http://www.yeegle.com/artic...

大头客的专栏 119

一次could not be injected because it is a JDK dynamic proxy的问题分析

1.问题的描述:springBoot 的版本1.5.9.RELEASE 对应spring的版本4.3.11.RELEASE javamelody-spring-boot-starter的版本是1.71.0,这是此次问题出现环境。 在本地启动的时候报could not be injected because it is a JDK dynamic proxy,字面的意思就是@Autowire...

weixin_42739473的博客 1万+

.NET Interceptor with Dynamic Proxy

在方法执行的前后做一个操作,比如写日志等,但又不想侵入性太大,可以考虑使用动态代理来实现。 1.下载Castle Install-Package Castle 2.示例代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading;

tomcat的专栏 1116

Dynamic Proxy

  http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html   Interestingly, you can have a proxy class that implements multiple interfaces. However, there are a few restrictions on the int...

k1280000'website 141

spring-boot 事务异常: because it is a JDK dynamic proxy that implement

使用spring-boot做事务管理时,出现异常:The bean 'xxx' could not be injected as a 'xx.xxxx' because it is a JDK dynamic proxy that implements: 搞了半天发现是因为代理的原因; 异常信息: Error starting ApplicationContext. To display t

huang_550的专栏 2万+

java reflect and dynamic proxy .Java反射和动态代理

根据风中叶老师的视频,自己练习的东西,希望大家也去浪曦看看视频。 推荐图书: [list] [*][img]http://image.taobao.com/bao/uploaded/http://img07.taobaocdn.com/bao/uploaded/i7/T1QIFnXaXgXXcg3jw9_103836.jpg_sum.jpg[/img] [url=http://s.c...

OlionkingO的专栏 184

The bean 'xxx' could not be injected as a 'xxx'because it is a JDK dynamic proxy that implements

启动springboot项目的时候示以下错误 1 Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2 2019-01-28 08:51:03.960 [main] ERROR o.s.b.diagnostic...

weixin_30342827的博客 882
上一篇: 设计模式 -(10)静态代理(static proxy)
下一篇: 设计模式 -(1)单例模式(singleton pattern)
sql2008help
博客等级 码龄11年 80粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值