代码编织梦想

JAVA动态代理代码梳理

当我们要为我们的代码附加别的功能的时候,我们往往写一个代理类来实现对当前类的封装,该代理类不实现具体的代码逻辑,只是提供了额外的功能,但如果我有很多的类需要封装一样的功能,那么我就得写很多的代理类,这种方式耗时严重且不易维护,是极为不可取的。所以JAVA为我们提供了动态代理的方式来一劳永逸,貌似大名鼎鼎的AOP就是通过动态代理的方式实现的,那我们来写一个动态代理的例子。

首先我们需要一个接口,作为被代理类的接口

package com.armandhe.dynamicproxy;

public interface ProxyInterface {
    public void printName();
}

然后定义一个实现类

package com.armandhe.dynamicproxy;

public class ProxyInterfaceImpl implements ProxyInterface{
    @Override
    public void printName() {
        System.out.println("my name is armandhe");
    }
}

然后定义我们的InnovcationHandler实例,这里我把调用类写在一起了

package com.armandhe.dynamicproxy;

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

public class DynamicProxyTest {
    public static void main(String[] args) {
        ProxyInterfaceImpl proxyInterface = new ProxyInterfaceImpl();
        ClassLoader classLoader = ProxyInterface.class.getClassLoader();
        ProxyInterface proxyInstance = (ProxyInterface) Proxy.newProxyInstance(classLoader, new Class[]{ProxyInterface.class}, new DynamicProxyHandler(proxyInterface));
        proxyInstance.printName();

    }
}

class DynamicProxyHandler implements InvocationHandler, Serializable {
    private final Object proxyedClass;
    public DynamicProxyHandler(Object proxyedClass) {
        this.proxyedClass =proxyedClass;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("添加的前置内容");
        Object invoke = method.invoke(proxyedClass, args);
        System.out.println("添加的前置内容");
        return invoke;
    }
}

这里注意到我们定义的处理器必须实现InvocationHandler, Serializable两个接口,一个是处理器,一个是反序列化标识,然后我们还得重写其invoke方法。

现在万事俱备只欠东风,我们直接打断点开始调试
在这里插入图片描述
在java.lang.reflect.Proxy#newProxyInstance方法中首先通过java.lang.reflect.Proxy#getProxyClass0方法获取一个Proxy 的Class实例,然后传入一个Innovacation的Class实例对象获取到对应的构造方法,最后利用反射调用获取到一个我们被代理类的Proxy类实例。
所以我们代理类的所有生成逻辑都在getProxyClass0这个方法中
该方法首先会从proxyClassCache缓存中检查被代理类的代理类实例是否已经生成了,如果生成则直接返回该实例,否则会调用subKeyFactory.apply方法获取subkey(干啥的没看懂),然后生成一个Factory(只有一些赋值操作),然后判断supplier是否为空,如果为空则继续循环,并为其赋值为factory,这时候其就不为空了然后会调用到supplier.get()方法
在这里插入图片描述
这里首先还是检查subkey是否有缓存,这时候很明显是有的且返回一个supplier对象,上面提到了会将Factory赋值为supplier,所以第一个判断假,直接到断点处,会调用valueFactory.apply,valueFactory为一个ProxyClassFactory对象。
在这里插入图片描述
这里直接获取了当前接口的Class实例
在这里插入图片描述
这里设置了生成的代理类的包名
在这里插入图片描述
这里设置类代理类的全类名,可以观察导生成的代理类类名已$Proxy加一个数字开头,数字是递增的以我们传入的接口数为准
在这里插入图片描述
然后会调用sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)生成代理类的字节码文件,这里面全是直接操作字节码,实在牛皮,然后调用java.lang.reflect.Proxy#defineClass0链接类完成类加载,defineClass0是一个本地方法,熟悉java类架子应该知道,在默认的类加载器中也是使用的该方法链接类。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/18f2ec10dc1b4cebb1b6e4f756b015e0.png) sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)首先在加载过程中就完成了代理类的生成,这很明显是一个饿汉式的单例模式。调用构造方法就进行了一些赋值操作。
然后调用sun.misc.ProxyGenerator#generateClassFile方法最终实现类加载,然后会saveGeneratedFiles是否保存生成的代理类文件,这个值通过设置系统属性sun.misc.ProxyGenerator.saveGeneratedFiles设置

在这里插入图片描述

在这里插入图片描述
从上到下一次完成将hashcode equals toString方法添加到proxyMethods中,将代理方法添加到sigmethods中
将被代理类方法加入到proxyMethods中
校验方法返回值类型
添加构造方法
然后就是一波操作字节码的逆天操作。。。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_32731075/article/details/124976106

详解java动态代理机制以及使用场景(一)_英雄郑旺的博客-爱代码爱编程_java动态代理的应用场景

说起java动态代理,在我刚开始学java时对这项技术也是十分困惑,明明可以直接调通的对象方法为什么还要使用动态代理?随着学习的不断深入和工作经验的积累,慢慢的体会并理解了java动态代理机制。昨天再给公司新同事做技术培训时有同学就对动态代理产生了疑问,我这里梳理一遍一并记录一下,方便大家查看对自己也是加深记忆。 (1)什么是代理? 大道理上讲代理是一

详解java代理机制(静态代理、动态代理)以及使用场景_venlenter的博客-爱代码爱编程_java中代理的使用场景

说起java动态代理,在我刚开始学java时对这项技术也是十分困惑,明明可以直接调通的对象方法为什么还要使用动态代理?随着学习的不断深入和工作经验的积累,慢慢的体会并理解了java动态代理机制。昨天再给公司新同事做技术培训时有同学就对动态代理产生了疑问,我这里梳理一遍一并记录一下,方便大家查看对自己也是加深记忆。 (1)什么是代理? 大道理上

java动态代理-实战_普通网友的博客-爱代码爱编程_java动态代理实战

只要是写Java的,动态代理就一个必须掌握的知识点,当然刚开始接触的时候,理解的肯定比较浅,渐渐的会深入一些,这篇文章通过实战例子帮助大家深入理解动态代理。 说动态代理之前,要先搞明白什么是代理,代理的字面意思已经很容易理解了,我们这里撇开其他的解释,我们只谈设计模式中的 代理模式 什么是代理模式(Proxy) 定义:给目标对象提供一个代理对象,并由

基础 | java的反射与动态代理_丙子先生的博客-爱代码爱编程_java反射和动态代理

关于「反射」请参看Class类详解(反射)部分。 动态代理作为Java反射的主要应用之一,其在多种JavaEE框架中均有使用,如Spring框架中AOP的实现原理就是动态代理,面试中提到AOP也必定会问 「谈谈对动态代

java知识点梳理:动态代理_打不死的小黑的博客-爱代码爱编程

通常认为,Java是静态的强类型语言,但是因为提供了类似反射等机制,也具备了部分动态类型语言的能力。 本文参照:极客时间-《java核心技术36讲》-第6讲 反射机制 反射机制是Java语言提供的一种基础功能,赋予程序

java 原生基于接口的动态代理_萧萧九宸的博客-爱代码爱编程

文章目录 参考文章前言JAVA 原生动态代理例子一:一个只会打印被调用方法的代理步骤一: 创建 Invocation Handler步骤二: 创建 Proxy Instance 例子二:可以代理多个接口的 In

Java 动态代理及 RPC 框架介绍-爱代码爱编程

点击上方“芋道源码 做积极的人,而不是积极废人! 源码精品专栏 

java动态代理-爱代码爱编程

原文:https://blog.csdn.net/u011784767/article/details/78281384   说起java动态代理,在我刚开始学java时对这项技术也是十分困惑,明明可以直接调通的对象方法为什么还要使用动态代理?随着学习的不断深入和工作经验的积累,慢慢的体会并理解了java动态代理机制。昨天再给公司新同事做技术培训时有同

Java进阶之注解和反射及动态代理-爱代码爱编程

前言 Android注解在之前都没用过,只知道最简单的 @override,最新心血来潮想学习下,找了一些资料,将学到的知识做下记录。 一、注解的含义 Java 注解(Annotation)又称 Java 标注,是 JDK1.5 引入的一种注释机制。是元数据的一种形式,提供有关于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。 著

java动态代理,轻轻松松从入门到精通-爱代码爱编程

动态代理、动态代理、动态代理,首先它是动态的,然后他能实现代理模式。 “动态”、“代理”,这两个词将贯穿全文。 一、什么是动态代理 java的动态代理,首先它是用来实现**“代理模式**”的。 然后他是动态的可以灵活的代理**“任何类”**【当然这个类需要有接口】。 我们先来看看动态代理能实现的效果。 如上示意图,类TestA、

Java静态代理与动态代理-爱代码爱编程

先粘贴一篇大佬的博文 「Java动态代理作用是什么」,本文是对其学习笔记。 代理(Proxy)是一种设计模式,通过代理对象来访问目标对象,目的是在目标对象的基础上进行增强,例如增加一些额外的功能。Java中的代理主要分为静态代理和动态代理。 静态代理 为每一个类都编写一个对应的代理类,两个类都实现同样的接口。在创建一个代理对象的时候,需要向其构造器

代理模式———动态代理-爱代码爱编程

动态代理 动态代理凭借其灵活性在框架中有着广泛的应用,下面简单记录一下我的学习理解; 代理模式: 基本概念 在百度百科中没有动态代理的概念,但是动态代理其实就是代理模式中的一种,所以在了解动态代理前最好先了解一下代理模式; 代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式; 代理模式就是为其他对象提供一种代理以控制对这个对

java 单元测试指北_单元测试命名-爱代码爱编程

每个程序员在修改代码的时候都希望有测试,而在写代码时,都不想写测试。 为什么要写单元测试 首先,只有经过测试的代码,代码质量才会更高。其次,如今早已不是单打独斗的时代,团队中的服务不是你自己一个人在维护,如果你不写测试,

java多线程学习之线程池赏析_java 线程fifo-爱代码爱编程

1了解概念:什么是线程池 Thread pool线程池,顾名思义就是由若干个线程“Thread类型对象”所组成的一个"池",但是切勿只认为Thread pool(线程池)内部就仅仅只有Thread类型对象(线程),这样理解是不够准确的。因为Thread pool内还有"任务队列",任务队列:Queue<Runnable>  tasksWork

通过shiro完成组织机构的登录、查询、退出操作_getsubject(servletrequest,servletresponse).login-爱代码爱编程

版权声明:严禁用于任何商业用途的转发! 注意: 1.这是一篇探讨性的文章,并不能作为指导性内容 2.具体的shiro认证流程等不做说明 3.在此之前,我尝试过利用shiro的ThreadLocal、数据库持久化等等手段,均没有达到理想中的效果!特别是ThreadLocal,存储后不论我怎么修改代码,一直获取不到写入的信息,有清楚原因的大大烦

java经典面试题分享_java面试刷题分享知识点-爱代码爱编程

前言: 由于临近期末考试,考试也比较密集,所以断更了好多天。最近复习Java的基础,发现好多知识都淡忘了,因此写下这篇文章帮助自己更好地加深印象,并且希望能帮助到各位小伙伴儿😉😉。 本篇文章适合正在学习Java基础的小伙伴儿

java动态代理-爱代码爱编程

Java动态代理 引言 因为在学习Spring AOP,其中用到了Java动态代理机制,所以好好把动态代理模式梳理了一遍。如有疑问或问题,欢迎在评论区探讨~ 代理设计模式 原理:给某一个对象提供一个代理,并由代理对