Java动态代理概述和手写实现动态代理

手写一个简化版的Dubbo框架 在学习了Dubbo之后, 我发现自己好像了解了Dubbo的实现原理, 又好像不是很了解, 毕竟我只是背诵了下概念, 没有深入的去看源码. 这里我就来手写一个简化版的Dubbo框架, 通过动手实践来深入理解Dubbo的实现原理. Dubbo的实现原理 RPC调用的过程 我们先来看下RPC调用的过程. 服务容器负责启动,加载,运行服务提供者。 服务提供者在启动时,向注册中心注册自己提供的服务。 服... 阅读详情

一:前提

Spring中最重要的两种思想:控制反转IOC(Inversion of Control)和面向切面编程AOP(Aspect-Oriented Programming),而AOP最重要的原理就是动态代理,今天我们谈一下动态代理。动态代理顾名思义是代替别人做某些事,它自己不干,让代理帮他做。别的不多说,直接上代码(举的例子可能不恰当)!

二:基于JDK的动态代理

1:因为Java的动态代理是基于接口的,所以先定义一个顶级接口Person

package dynamicProxy.jdkDynamic;
/**
 * 顶级接口
 */
public interface Person {
    public void speak();
}

2:写一个Person的实现类GuangDongPerson 

package dynamicProxy.jdkDynamic;

/**
 * 实现类
 * */
public class GuangDongPerson implements Person {

    @Override
    public void speak() {
        System.out.println("我说的是~¥#~&~#");
    }
}

3:找一个翻译作为代理类,进行翻译普通话。

package dynamicProxy.jdkDynamic;

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

public class Translation implements InvocationHandler {

    private Person target;

    public Translation(Person target) {
        this.target = target;
    }

    public static Object getInstance(Person target){
        Class<? extends Person> clazz = target.getClass();
        System.out.println(clazz.getName());
        Object poxy = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new Translation(target));
        System.out.println(poxy.getClass().getName());
        return poxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是翻译,你说话我翻译,请说话!");
        Object invoke = method.invoke(target,args);
        System.out.println("他说的是xxxxxxxxxx");
        return invoke;
    }
}

说明:

1:Proxy.newInstance()方法

        * 第一个参数为目标类的类加载器

        * 第二个参数为目标类的接口集合,JDK动态代理目标类必须实现一个接口,这是为了保证生成的代理类和目标类之前的强一致性关系

        * 第三个参数为InvocationHandler接口的实现类,这里直接通过匿名内部类实现,重写了invoke方法

  2:InvocationHandler接口实现类

        * 实现该类必须重写invoke()方法,动态代理实现在代理类中该接口的实现类调用该方法,并在该方法中反射执行该方法完成整个动态代理流程;

        * 第一个参数为生成的动态代理对象;

        * 第二个参数为动态代理在客户端执行的方法;

        * 第三个参数为该方法的参数列表;

        * 通过反射来完成方法调用;

4:测试类

package dynamicProxy.jdkDynamic;

import dynamicProxy.jdkDynamic.custom.TLGuangDongPerson;
import dynamicProxy.jdkDynamic.custom.TLPerson;
import dynamicProxy.jdkDynamic.custom.TLTranslation;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

public class Test {

    public static void main(String[] args) throws Exception{

        Person translationInstance = (Person)Translation.getInstance(new GuangDongPerson());
        translationInstance.speak();

        byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
        FileOutputStream outputStream = new FileOutputStream("E:\\$Proxy0.class");
        outputStream.write(bytes);
        outputStream.close();
//        TLPerson translationInstance = (TLPerson)TLTranslation.getInstance(new TLGuangDongPerson());
//        translationInstance.speak();
//
//        byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
//        FileOutputStream outputStream = new FileOutputStream("E:\\$Proxy0.class");
//        outputStream.write(bytes);
//        outputStream.close();
    }
}

5:测试结果

dynamicProxy.jdkDynamic.Test
//未被代理之前的类
dynamicProxy.jdkDynamic.GuangDongPerson
//代理之后的类
com.sun.proxy.$Proxy0

我是翻译,你说话我翻译,请说话!
我说的是~¥#~&~#
他说的是xxxxxxxxxx

Process finished with exit code 0

注:看到上面的输出,可以很明显的看代理之后的类编程了$Proxy0,下面是此类的反编译结果

import dynamicProxy.jdkDynamic.Person;
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 Person {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    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 void speak() throws  {
        try {
            super.h.invoke(this, m3, (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);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("dynamicProxy.jdkDynamic.Person").getMethod("speak");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

总结:Java动态代理使用反射机制进行代理,可以看到该虚拟类继承Proxy类并实现了目标类顶层接口,并反射获取了目标类中的所有方法的Method对象,同时,虚拟类也同时重写了目标类的所有方法,并通过super.h.invoke(this, m3, (Object[])null)的方式进行调用。

三:手写实现JDK动态代理

步骤:

1:TLPerson类,定义newInstance()方法,进行代理对象创建

  • 在该方法中首先需要输出代理类的.java文件
  • 编译该.java文件生成.class文件
  • 通过类加载器加载该.class文件
  • 生成该.class文件的事例对象作为代理对象返回

2:TLInvocationHandler接口,定义invoke()方法,在代理类中进行目标方法调用

  • 在.java文件中,定义构造器,传递该类引用
  • 通过SelfInvocationHandler实现类对象调用invoke()方法,实现代理方式的方法调用

3:TLClassLoader,自定义类加载器,继承JDK的ClassLoader类,实现自定义的加载方式

具体操作:

1:创建顶级接口

package dynamicProxy.jdkDynamic.custom;

public interface TLPerson {
    public void speak();
}

2:创建实现类

package dynamicProxy.jdkDynamic.custom;

public class TLGuangDongPerson implements TLPerson{
    @Override
    public void speak() {
        System.out.println("我说的是~¥#~&~#");
    }
}

3:使用自己的TLClassLoader代替JDK的ClassLoader,重写findClass(String name)方法。

package dynamicProxy.jdkDynamic.custom;

import dynamicProxy.custom.SelfClassLoader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

public class TLClassLoader extends ClassLoader {
    private File classPathFile;

    public TLClassLoader() {
        String classPath = TLClassLoader.class.getResource("").getPath();
        this.classPathFile = new File(classPath);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String className = TLClassLoader.class.getPackage().getName() + "." + name;
        if (null != classPathFile) {
            File classFile = new File(classPathFile, name + ".class");
            if (classFile.exists()) {
                FileInputStream in = null;
                ByteArrayOutputStream out = null;
                try {
                    in = new FileInputStream(classFile);
                    out = new ByteArrayOutputStream();
                    byte[] bytes = new byte[1024];
                    int len;
                    while((len = in.read(bytes)) != -1) {
                        out.write(bytes, 0, len);
                    }
                    return defineClass(className, out.toByteArray(), 0, out.size());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (null != in) {
                            in.close();
                        }
                        if (null != out) {
                            out.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return null;
    }
}

4:使用自己的TLInvocationHandler代替JDK的InvocationHandler,重写invoke(Object proxy, Method method, Object[] args)方法。

package dynamicProxy.jdkDynamic.custom;

import java.lang.reflect.Method;

public interface TLInvocationHandler {

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

5:使用自己的TLProxy代替JDK的Proxy

package dynamicProxy.jdkDynamic.custom;

import com.sun.org.apache.regexp.internal.RE;
import dynamicProxy.custom.SelfInvocationHandler;
import dynamicProxy.custom.SelfProxy;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TLProxy {
    private static final String LN = "\r\n";
    public static Object newProxyInstance(TLClassLoader loader, Class<?>[] interfaces, TLInvocationHandler h) throws Exception {
        // 动态生成源代码
        String srcClass = generateSrc(interfaces);
        // 输出Java文件
        String filePath = TLProxy.class.getResource("").getPath()  + "$ProxyO.java";
        System.out.println(filePath);
        FileWriter fileWriter = new FileWriter(filePath);
        fileWriter.write(srcClass);
        fileWriter.flush();
        fileWriter.close();
        // 编译Java文件为class文件
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Iterable iterable = fileManager.getJavaFileObjects(filePath);
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, iterable);
        task.call();
        fileManager.close();
        // 加载编译生成的class文件到JVM
        Class<?> proxyClass = loader.findClass("$ProxyO");
        Constructor<?> constructor = proxyClass.getConstructor(TLInvocationHandler.class);
        // 删掉虚拟代理类
        File file = new File(filePath);
        file.delete();
        // 返回字节码重组以后的代理对象
        return constructor.newInstance(h);
    }
    private static String generateSrc(Class<?>[] interfaces) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("package dynamicProxy.jdkDynamic.custom;" + LN );
        stringBuilder.append("import dynamicProxy.jdkDynamic.custom.TLPerson;" + LN);
        stringBuilder.append("import java.lang.reflect.Method;" + LN);
        stringBuilder.append("public class $ProxyO implements " + interfaces[0].getName() + "{" + LN);
        stringBuilder.append("TLInvocationHandler h;" + LN);
        stringBuilder.append("public $ProxyO(TLInvocationHandler h) {" + LN);
        stringBuilder.append("this.h = h;" + LN);
        stringBuilder.append("}" + LN);

        for (Method method : interfaces[0].getMethods()) {
            stringBuilder.append("public " + method.getReturnType().getName() + " " + method.getName() + "() {" + LN);
            stringBuilder.append("try {" + LN);
            stringBuilder.append("Method m = " + interfaces[0].getName() + ".class.getMethod(\"" + method.getName() + "\", new Class[]{});" + LN);
            stringBuilder.append("this.h.invoke(this, m, null);" + LN);
            stringBuilder.append("} catch(Throwable able) {" + LN);
            stringBuilder.append("able.getMessage();" + LN);
            stringBuilder.append("}" + LN);
            stringBuilder.append("}" + LN );
        }
        stringBuilder.append("}" + LN);
        return stringBuilder.toString();
    }
}

6:创建手写翻译类

package dynamicProxy.jdkDynamic.custom;

import dynamicProxy.jdkDynamic.Translation;

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

public class TLTranslation implements TLInvocationHandler {
    private TLPerson target;

    public TLTranslation(TLPerson target) {
        this.target = target;
    }

    public static Object getInstance(TLPerson target) {
        try {
            Class<? extends TLPerson> clazz = target.getClass();
            System.out.println(clazz.getName());
            Object poxy = TLProxy.newProxyInstance(new TLClassLoader(), clazz.getInterfaces(), new TLTranslation(target));
            System.out.println(poxy.getClass().getName());
            return poxy;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        System.out.println("我是翻译,你说话我翻译,请说话!");
        Object invoke = method.invoke(target,args);
        System.out.println("他说的是xxxxxxxxxx");
        return invoke;
    }
}

7:测试类

package dynamicProxy.jdkDynamic;

import dynamicProxy.jdkDynamic.custom.TLGuangDongPerson;
import dynamicProxy.jdkDynamic.custom.TLPerson;
import dynamicProxy.jdkDynamic.custom.TLTranslation;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

public class Test {

    public static void main(String[] args) throws Exception{

//        Person translationInstance = (Person)Translation.getInstance(new GuangDongPerson());
//        translationInstance.speak();
//
//        byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
//        FileOutputStream outputStream = new FileOutputStream("E:\\$Proxy0.class");
//        outputStream.write(bytes);
//        outputStream.close();
        TLPerson translationInstance = (TLPerson)TLTranslation.getInstance(new TLGuangDongPerson());
        translationInstance.speak();

        byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
        FileOutputStream outputStream = new FileOutputStream("E:\\$Proxy0.class");
        outputStream.write(bytes);
        outputStream.close();
    }
}

8:测试结果

dynamicProxy.jdkDynamic.custom.TLGuangDongPerson
/F:/project/TimeTest/target/classes/dynamicProxy/jdkDynamic/custom/$ProxyO.java
dynamicProxy.jdkDynamic.custom.$ProxyO
我是翻译,你说话我翻译,请说话!
我说的是~¥#~&~#
他说的是xxxxxxxxxx

Process finished with exit code 0

这仅是一个理解动态代理的思路,可能会给你一点启发,共同进步!

 

 

 

 

 

 

 

 

 

 

 

深入理解Java动态代理与代码模拟JDK实现动态代理【JAVA核心】 前言文章目录如下,便于快速索引一、什么叫代理?二、什么叫动态代理?三、动态代理有什么优势?四、动态代理的JDK实现原理    4.1核心类/接口    4.2 代理类$Proxy0解析    4.3 动态代理的经典使用五、手写代码模拟JDK动态代理六、参考资料项目源码已经上传,欢迎点击下载~先将自己总结的Java动态代理UML图放在前面,用相同的颜色代表同一个或本质上相同的类与方法,便于大家理解。... 阅读详情

相关推荐

两万字吐血总结,代理模式及手写实现动态代理(aop原理,基于jdk动态代理)

代理模式及手实现动态代理(aop原理)一、代理模式1. 定义2. 示例(1)静态代理(2)动态代理3. 通用类图4. 代理模式的优点二、jdk动态代理实现原理1. jdk动态代理源码分析(通过该示例学会阅读源码的方法)2.jdk动态代理生成的代理类的源码3.总结三、手写实现jdk动态代理 一、代理模式 熟悉代理模式的可以直接点击目录第二章,jdk动态代理实现原理,本文的精髓所在,通过这个例子,教大家如何去学习源码。 1. 定义 代理模式(Proxy Pattern) 是一个使用频率非常高的设计模式,其定义如下: Provide a surrogate or placeholder for an

从简入繁详解代理模式(手写JDK动态代理)

1简单概要 代理模式:指为其他对象提供一种代理来控制对这个对象的访问。 代理模式主要有两个目的: ①保护目标对象; ②增强目标对象。 它的类图如下: 2分类与详解 2.1 静态代理 举个栗子:儿子正在找对象,而父母希望儿女早点找到另一半,于是在儿子找对象的同时帮他物色: interface Person{ void findLove(); } public class Son implements Person { public void findLo...

dms2017的博客 1083

直流有刷电机控制 - 驱动电路(二)

1.如图所示为最常见的推挽驱动电路,我附加了具有正反转功能的电机驱动控制,正反转是由两个继电器组成。使用推挽电路来驱动NMOS管时充电电流和放电电流都很大,因此NMOS管导通快,关断也快,而且NMOS温度不会很高。下面来介绍一下该电路的原理。(1)PWM_MCU是由单片机给出的PWM波信号,该信号是由一些列高低电平的方波构成。当信号为高电平的时候Q3导通,经过R47再到Q5的g极,此时mos导通,如果是K1闭合是正转那么K2闭合就是反转。(2)当PWM低电平时使得Q3关断,Q6导通。

u011030644的博客 4721

Python学习笔记13:进阶篇(二)类的继承与组合

Python进阶知识,类的集合和组合

weixin_48668564的博客 1850

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

liang007dudu的博客 1万+

【现代信号处理】01 -概率论与随机过程回顾

概率论与随机过程回顾 文章目录概率论与随机过程回顾1. 统计模型的相关概念1.1 统计实验(不确定性)1.2 样本点1.3 样本空间Ω1.4 概率1.5.统计模型是先验的2. 概率和统计的差异2.1 联系2.2 差异2.3.1 概率和统计问题的三要素2.3.1.1 model-模型2.3.1.2 data-数据2.3.1.3 decision-决策2.3.2 关系图3. 样本空间的重要性3.1 贝朗特悖论3.1.1 解法一3.1.2 解法二3.1.3 解法三3.2 结论4.概率相关的概念4.1 随机变量4.

qq_41741344的博客 1410

JDK动态代理实现原理以及手写实现JDK动态代理

JDK动态代理是采用字节重组,重新生成对象来替代原始对象,以达到动态代理的目的。在理清楚JDK动态代理的过程后,手写实现JDK动态代理过程。

积跬步,至千里。 868

[原创]Linux 802.11n CSI tool安装教程(亲测可用)

Linux 802.11n CSI tool安装教程 前言 网上关于Intel5300 CSI tool的教程繁多,实际有效的可以说极少,各种疏漏错误。装的时候被坑无数次,终于调通。其实装这个工具并不太难,但是很多人把它弄得极其复杂,所以写这篇博客来帮助和我有一样困扰的人。我基本沿用的是官方文档旧版本的安装方案,针对其冗杂之处做了大量改进。 旧版安装教程: http://dhalperi....

u014645508的博客 4万+

【设计模式】——纯手写实现JDK动态代理

前言 在【设计模式】——代理模式(静态)以及【设计模式】——代理模式(动态)中,我们已经基本了解了什么是代理模式,以及什么是静态代理,什么是动态代理。 JDK动态代理以及Cglib动态代理其实底层实现原理都是字节码的重组,不过各自对应的代理场景不同,本文我们重点研究jdk动态代理。 通过前文的了解,我们已经知道在JDK动态代理中是JDK动态的帮我们生成一个名为$Proxy0的代理类,那么,我.........

我爱吃土豆 6569

在昇腾910B服务上部署搭建适配PDF解析工具Mineru2.5开源项目

本文介绍了在昇腾910B服务器上部署开源PDF解析工具Mineru2.5的过程。首先从昇腾社区下载mindie镜像并运行容器,安装系统依赖。针对部署过程中遇到的多个报错问题(如torchvision与torch版本不匹配、昇腾软件栈与NumPy 2.0不兼容等),提供了具体解决方案和兼容版本。通过设置环境变量、安装指定版本的Python依赖包,成功部署Mineru项目并下载模型。最后运行测试,验证了在NPU设备上运行pipeline的可行性。整个过程详细记录了版本适配和错误处理方法,为类似部署场景提供了参考

一起加油吧 2165

TJA1445/TJA1465 CAN收发器硬件设计与软件配置实战指南

控制器局域网(CAN)总线是汽车电子和工业控制领域实现电子控制单元(ECU)间可靠通信的核心技术。其工作原理是将数字信号转换为差分信号进行抗干扰传输,技术价值在于构建稳定、高效的分布式实时控制系统。随着汽车电子架构向域集中式演进,对CAN总线的通信速率、网络复杂度和静态功耗提出了更高要求,这催生了支持CAN FD协议和智能电源管理的新一代高速CAN收发器。在车载网关、域控制器及工业网络节点等应用场景中,NXP的TJA1445和TJA1465系列收发器凭借其部分组网(Partial Networking)和选

weixin_29655587的博客 411

不用JDK的动态代理,手写JDK动态代理

App ClassLoader实现步骤:继承ClassLoader并覆盖findClass。实现newProxyInstance共五个步骤。

忆亦何为的博客 701

合规批量下载美国上市公司年报数据的一些经验和总结

本文总结了使用Python脚本批量下载和处理美国上市公司SEC报告的技术经验。通过CIK代码查询SEC EDGAR系统,生成特定日期和报告类型的URL,并使用Selenium和Requests库下载报告内容。流程包括数据获取、文件下载、Excel处理和多线程优化,确保高效处理几百条数据。关键技术挑战包括SEC访问限制、动态网页内容和数据完整性,解决方案包括设置合规的User-Agent、使用Selenium模拟浏览器行为以及错误日志记录。最佳实践包括模块化设计、多线程优化和严格遵守SEC合规性。该自动化流程

jyfool的博客 1640

[Java|面试] 面试被问Java的动态代理机制,能说说吗

Java的动态代理机制 文章目录Java的动态代理机制0. 什么是代理1.动态代理和静态代理的区别2. 使用代理的情况3. 动态代理的构成4. JDK中的动态代理5. 手写一个JDK动态规划的demo6. 总结 0. 什么是代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。 这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色。 代理这种设计模式是通过不直接访问被代理对象的方式,而访问被代理对象的方法。 从Java面向对象编程的角度,代理模

喜欢前端的后端 MelodyJerry 1万+

RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块

本文记录的是利用模块优化的目标检测网络模型。的作用在于克服了常见模块无法同时吸收CNN 效率建模局部特征和利用Transformer 动态建模能力学习长距离交互的问题。相比一些复杂结构或多个混合模块的方法,能更好地权衡模型成本和精度。本文将其用于的模型改进和二次创新,更好地突出重要特征,提升模型性能。Rethinking Mobile Block for Efficient Attention-based Models从微观角度看,由和组成。及其改进的实现代码如下: 四、创新模块 4.1 改进点1⭐ 模块

Limiiiing的博客 817

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别

上篇介绍了一下静态代理:Java中的代理模式——静态代理以及分析静态代理的缺点 也分析了一下静态代理的缺点: 1、由于静态代理中的代理类是针对某一个类去做代理的,那么假设一个系统中有100个Service,则需要创建100个代理类 2、如果一个Service中有很多方法需要事务(增强动作),发现代理对象的方法中还是有很多重复的代码 3、由第一点和第二点可以得出:静态代理的重用性不强 那怎...

曹举的个人博客 2万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

手写实现动态代理

一般来说最常见的动态代理是这么写的: 1,正常版本 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JDKProxy implements InvocationHandler { private Obje...

huffmanT的博客 943

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

手写实现一个动态代理框架

首先我们来了解一下代理模式,代理模式是二十三种设计模式中的其中一种,用于对目标对象进行代理增强。代理类通常和目标类实现同一个接口,这样我们就可以用一个接口类型变量去引用一个代理类对象,然后又可以当成目标对象去使用。.........当我们对目标对象做了代理之后,就可以在调用目标对象方法的前后添加一些增强的处理逻辑。// 前置增强逻辑post();// 后置增强逻辑@Override...

weixin_43889578的博客 456

手写Java动态代理

如图1所示,动态代理的使用 这篇文章讲解动态代理的原理,以及如何手写动态代理。 以下是有关动态代理的使用,这是JDK默认帮我们实现的动态代理。 public class Main implements InvocationHandler { static Person person=new PersonImp(); public static void main(Strin...

0xc 1037

java jdk动态代理和cglib动态代理对比,实现,区别

java jdk动态代理和cglib动态代理对比,实现,区别 jdk动态代理和cglib动态代理对比 jdk动态代理 特点 Interface:对于JDK Proxy,业务类是需要一个Interface的,这是一个缺陷; Proxy:Proxy类是动态产生的,这个类在调用Proxy.newProxyInstance()方法之后,产生一个Proxy类的实力。实际上,这个Proxy类也是存在的,不仅...

plumblum的博客 1万+

Java AOP的实现原理和手写实现,支持JDK动态代理,Javassist代理,Cglib代理

Java AOP的实现原理和手写实现,支持JDK动态代理和Cglib代理 概述 面向切面编程已经在我们的平常工作中经常会用到, 平常我们在使用的都是使用spring封装的aop模块, 使用的时候只要配置几个注解就能实现逻辑了,非常的方便. 但是使用的方便也就意味着其封装的复杂, 另外spring的aop也是有其的演进,从最早的只能通过实现接口+xml配置,到现在@Aspect的支持来实现声明式的变...

cdy1996的博客 502

手写实现JDK动态代理

前言 在Java领域,动态代理应用非常广泛,特别是流行的Spring/MyBatis等框架。JDK本身是有实现动态代理技术的,不过要求被代理的类必须实现接口,不过cglib对这一不足进行了有效补充。本篇博客将涉及2个话题:第一,JDK动态代理的实现原理,带你探索动态代理的实质面目;第二,自己动手写代码去实现JDK动态代理,去创造世界! JDK动态代理 先写一个例子,感性认识下动态代理~ 业务接口: interface 业务实现类: interface impl 业务处理类:.

YvesHe的专栏 554

java动态代理实现

转载:https://www.cnblogs.com/xifengxiaoma/p/9371771.html 目录  一、代理模式 二、静态代理 三、动态代理 关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理。  一、代理模式    代理模式是常用的java设计模式,他的特征是代理类与委托类...

weixin_40663800的博客 7944

java的动态代理如何实现

JDK 的动态代理和 CGLIB 都有各自的优点和缺点,具体使用哪种方式取决于具体的需求和场景。如果被代理的类已经实现了接口,那么可以优先考虑使用 JDK 的动态代理;如果被代理的类没有实现接口,或者需要对类的所有方法进行代理,那么可以考虑使用 CGLIB。

蒾酒的博客 1507
上一篇: 设计模式之---动态代理
下一篇: Centos7上安装docker (转)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值