Spring AOP带你了解整个流程,让面试官只能仰望

文章目录

    • 一,介绍
    • 二,什么是JDK动态代理以及CGLIB代理
    • 三,源码流程图
    • 小结

一,介绍

在这里插入图片描述
提示:解析

A[“JavaConfig”] --> B[“@EnableAspectJAutoProxy”]: 在Spring配置中,启用AspectJ自动代理功能。这是一个注解,可以轻松地启用AOP功能。
B --> C[“注册AnnotationAwareAspectJAutoProxyCreator”]: Spring AOP注册一个AnnotationAwareAspectJAutoProxyCreator bean,它负责根据切点表达式自动为符合条件的bean创建代理。
C --> D[“BeanPostProcessor”]: 在Spring AOP中,BeanPostProcessor接口用于自定义在实例化、配置、初始化等阶段对bean的处理逻辑。Spring AOP会为所有bean注册一个实现了BeanPostProcessor接口的bean。
D --> E[“解析切面”]: BeanPostProcessor在bean初始化后,会解析切面。切面是一个包含通知和切点对象的对象。
E --> F[“解析通知和切点”]: 解析切面后,会解析通知和切点。通知是切面中的方法,切点是这些方法应该被应用到哪些调用的表达式。
F --> G[“缓存Advisor”]: 将解析得到的通知和切点缓存为Advisor对象。Advisor是切面的一种表示形式,它包含了通知和切点信息。
G --> H[“创建动态代理”]: 根据Advisor对象创建动态代理。动态代理是一种运行时生成的类,它实现了目标bean的接口,并将调用转发给目标bean。
H --> I[“判断Bean是否被切点匹配”]: 判断当前bean是否与切点表达式匹配。如果匹配,则进入下一步;否则,直接返回。
I --> J[“是”]: 如果当前bean与切点表达式匹配,则进入下一步。
J --> K[“选择代理创建方式”]: 选择动态代理的创建方式,可以选择JDK动态代理或CGLIB。JDK动态代理只能代理实现了接口的类,而CGLIB可以代理没有实现接口的类。
K --> L[“JDK动态代理或CGLIB”]: 根据上一步的选择,创建代理对象。如果选择了JDK动态代理,则获取目标bean的接口并使用Proxy.newProxyInstance方法创建代理对象;如果选择了CGLIB,则获取目标bean的类并使用CGLIB.Enhancer创建代理对象。
L --> M[“创建代理对象”]: 创建完代理对象后,进入下一步。
M --> V[“调用方法”]: 调用代理对象的方法。如果该方法被增强(即该方法被包含在通知链中),则进入下一步;否则,直接返回。
V --> W[“判断方法是否增强方法”]: 判断上一步调用的方法是否被增强。如果是,进入下一步;否则,根据实际情况进入17或18步。
W --> X[“是”]: 如果该方法被增强,则进入下一步。
X --> Y[“执行通知链”]: 执行通知链中的所有通知方法。这些通知方法会对目标bean的调用进行增强,例如记录日志、性能监控等。
Y --> Z[“调用链中的通知方法”]: 调用链中的第一个通知方法。这个方法会对目标bean的调用进行增强。然后依次调用链中的其他通知方法,直到最后一个通知方法执行完毕。
Z --> AA[“执行目标方法”]: 执行目标方法。这是原始的目标bean的方法调用,没有被增强过。

二,什么是JDK动态代理以及CGLIB代理

提示:JDK动态代理和CGLIB代理都是Java中的动态代理技术,它们在实现方式上有所不同。

JDK动态代理是基于Java反射机制的一种动态代理技术。它要求被代理的目标类必须实现至少一个接口,通过实现InvocationHandler接口来提供具体的代理逻辑。在代理类中,通过调用被代理接口的invoke方法来将方法调用转发给InvocationHandler进行处理。这种方式的优点是代理类与目标类之间解耦,但是要求目标类必须实现接口。

JDK动态代理的具体实现步骤如下:

定义一个接口,并让目标类实现该接口。
实现InvocationHandler接口,提供具体的代理逻辑。
在InvocationHandler实现类中,重写invoke方法,实现在代理类中将方法调用转发给目标类,并将目标类的返回值返回给调用者。
创建代理类实例,并将InvocationHandler实现类的实例作为参数传递给Proxy.newProxyInstance方法,创建代理对象。
通过代理对象调用目标类的方法时,实际上会调用InvocationHandler中的invoke方法进行处理。
CGLIB代理是一种基于CGLIB库的动态代理技术,它通过继承目标类来实现代理,不需要目标类实现接口。CGLIB代理通过生成一个继承目标类的子类来覆盖目标类的方法,并在覆盖的方法中提供代理逻辑。这种方式的优点是不需要修改目标类的代码,但是继承方式会导致代码的侵入性较高。

CGLIB代理的具体实现步骤如下:

定义一个继承自目标类的子类,并重写目标类的方法。
在重写的方法中提供代理逻辑,并调用目标类的方法。
创建子类的实例作为代理对象,并通过该对象调用目标类的方法时,实际上会调用子类重写的方法进行处理。
需要注意的是,在使用CGLIB代理时,需要注意目标类是否被final修饰,因为final修饰的类无法被继承。此外,还需要注意类加载器和字节码生成的问题,因为CGLIB库会根据目标类的字节码生成代理类的字节码。

在Spring框架中,默认情况下会使用JDK动态代理来实现AOP切面。如果目标类没有实现任何接口,Spring会尝试使用CGLIB代理来实现AOP切面。需要注意的是,在使用CGLIB代理时,需要注意目标类是否被final修饰。

三,源码流程图

提示:Java动态代理的源码流程图可以大致分为以下几个步骤:

创建InvocationHandler实例:该实例用于处理代理对象上的方法调用。
创建代理对象:通过Proxy类的静态方法newProxyInstance()创建代理对象,该方法需要传入三个参数:类加载器、代理类实现的接口列表和InvocationHandler实例。
调用代理对象的方法:当代理对象的方法被调用时,实际上会调用InvocationHandler实例的invoke()方法。
invoke()方法中处理方法调用:在invoke()方法中,可以进行方法调用的前后处理,例如记录日志、权限验证等。然后通过反射机制调用目标对象上的对应方法,并返回结果。
下面是一个简单的Java动态代理的源码流程图示例:

创建目标对象实例。
创建InvocationHandler实例,并将目标对象实例作为构造参数传入。
通过Proxy.newProxyInstance()方法创建代理对象,传入类加载器、目标对象实现的接口列表和InvocationHandler实例。
调用代理对象的方法,实际上会调用InvocationHandler实例的invoke()方法。
在invoke()方法中,通过反射机制获取目标对象上的对应方法,并记录日志或进行其他处理。
调用目标对象上的对应方法,并返回结果。
请注意,上述流程仅供参考,具体实现可能会因为不同的场景而有所不同。另外,流程图的具体表现形式可能因为文本限制而不太直观,可以结合代码和调试工具进行更深入的理解。

Java动态代理的源码实现涉及到Java反射机制和字节码技术,如果对这方面不太熟悉,建议先学习一下相关知识。`

创建InvocationHandler实例:该实例用于处理代理对象上的方法调用。
创建代理对象:通过Proxy类的静态方法newProxyInstance()创建代理对象,该方法需要传入三个参数:类加载器、代理类实现的接口列表和InvocationHandler实例。
调用代理对象的方法:当代理对象的方法被调用时,实际上会调用InvocationHandler实例的invoke()方法。
invoke()方法中处理方法调用:在invoke()方法中,可以进行方法调用的前后处理,例如记录日志、权限验证等。然后通过反射机制调用目标对象上的对应方法,并返回结果。

下面是一个简单的Java动态代理的介绍:

创建目标对象实例。
创建InvocationHandler实例,并将目标对象实例作为构造参数传入。
通过Proxy.newProxyInstance()方法创建代理对象,传入类加载器、目标对象实现的接口列表和InvocationHandler实例。
调用代理对象的方法,实际上会调用InvocationHandler实例的invoke()方法。
在invoke()方法中,通过反射机制获取目标对象上的对应方法,并记录日志或进行其他处理。
调用目标对象上的对应方法,并返回结果。
请注意,上述流程仅供参考,具体实现可能会因为不同的场景而有所不同。另外,流程图的具体表现形式可能因为文本限制而不太直观,可以结合代码和调试工具进行更深入的理解。
Java动态代理是一种在运行时创建代理类的技术,通过实现InvocationHandler接口来提供具体的代理逻辑。它适用于对实现了接口的类进行代理,也可以通过继承目标类的方式对没有实现接口的类进行代理。与CGLIB代理相比,JDK动态代理更加灵活和轻量级,但是要求目标类必须实现接口。在Spring框架中,JDK动态代理是默认的代理方式。
Java动态代理的源码实现涉及到Java反射机制和字节码技术,如果对这方面不太熟悉,建议先学习一下相关知识。

小结

Java动态代理是一种在运行时创建代理类的技术,通过实现InvocationHandler接口来提供具体的代理逻辑。它适用于对实现了接口的类进行代理,也可以通过继承目标类的方式对没有实现接口的类进行代理。与CGLIB代理相比,JDK动态代理更加灵活和轻量级,但是要求目标类必须实现接口。在Spring框架中,JDK动态代理是默认的代理方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/255993.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【尘缘送书第五期】Java程序员:学习与使用多线程

目录 1 多线程对于Java的意义2 为什么Java工程师必须掌握多线程3 Java多线程使用方式4 如何学好Java多线程5 参与方式 摘要:互联网的每一个角落,无论是大型电商平台的秒杀活动,社交平台的实时消息推送,还是在线视频平台的流量洪峰…

【C语言快速学习基础篇】之二控制语句、循环语句、隐式转换

文章目录 一、控制语句1.1、for循环1.2、while循环1.3、注意:for循环和while循环使用上面等同1.4、do while循环1.4.1while条件成立时1.4.2、while条件不成立时 C语言介绍 C语言是一门面向过程的计算机编程语言,与C、C#、Java等面向对象编程语言有所不同…

【微服务】springboot整合quartz使用详解

目录 一、前言 二、quartz介绍 2.1 quartz概述 2.2 quartz优缺点 2.3 quartz核心概念 2.3.1 Scheduler 2.3.2 Trigger 2.3.3 Job 2.3.4 JobDetail 2.4 Quartz作业存储类型 2.5 适用场景 三、Cron表达式 3.1 Cron表达式语法 3.2 Cron表达式各元素说明 3.3 Cron表达…

配置BFD状态与接口状态联动示例

1、BFD检测IP链路。 在IP链路上建立BFD会话,利用BFD检测机制快速检测故障。BFD检测IP链路支持单跳检测和多跳检测: BFD单跳检测是指对两个直连系统进行IP连通性检测,“单跳”是IP链路的一跳。 BFD多跳检测是指BFD可以检测两个系统间的任意路…

UDP通讯

本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点 这两种通讯方式不通的地方就是TCP是一对一通信 UDP是一对多的通信方式 接下来会一一讲解 UDP通信 主要的方向是一对多通信方式 UDP通信就是一下子可以通信多个对象,这就是UDP对比TCP的优势&am…

股市复苏中的明懿金汇:抓住新机遇

2023年对于明懿金汇来说是充满挑战与机遇的一年。面对复杂多变的市场环境,明懿金汇展现了其对市场趋势的敏锐洞察和卓越的策略适应能力。以下是该公司在2023年的主要投资策略和市场适应方式的详细分析。 随着2023年中国股市迎来反弹,明懿金汇迅速调整了…

Day04 Liunx高级系统设计4-信号

进程间通讯 引入 如何将 A 进程中的数据传入 B 进程呢 ? 我们要使用进程间通讯 概述 中文名 : 进程间通讯 英文名 :IPC 英文全称 :Inter Processes Communication 作用: 数据传输:一个进程需要将他的数据发送给另一个进程】 资源共享:多个进程可以…

从文字到使用,一文读懂Kafka服务使用

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

C++入门第十一篇----多态

前言: 和前面的继承一样,多态也是对类和对象的功能进行扩展,以让其更加好用的一个知识点,接下来,就让我们总结一下多态,这个依托了继承的一个重要知识点。 对多态的理解和多态的概念: 何为多…

如何把数据变成资产,企业数据资产化实施路径三部曲

在数字化时代,数据已经成为一种重要的资产,企业和个人都希望能够将数据变现。但并不是所有的数据都是资产,如何成为资产是当下企业关心的问题。下面就让我们一起来了解一下企业数据资产化的三个关键步骤:数据资源化、资源产品化和…

学习SQL大概要多久?有没有好的资料或者视频推荐呢?

【关注微信公众号:跟强哥学SQL,回复“笔试”免费领取大厂SQL笔试题。】 一、SQL认知 SQL(Structured Query Language)是一种用于管理和操作关系型数据库的标准化语言。通过SQL,使用简单的关键词和语法来表达复杂的数…

C++新经典模板与泛型编程:用成员函数重载实现std::is_class

用成员函数重载实现is_class std::is_class功能,是一个C11标准中用于判断某个类型是否为一个类类型(但不是联合类型)的类模板。当时在讲解的时候并没有涉及std::is_class的实现代码,在这里实现一下。简单地书写一个IsClass类模板…