首页 > 其他分享 >面试官:说说SpringAOP实现原理?

面试官:说说SpringAOP实现原理?

时间:2024-03-05 11:03:36浏览次数:29  
标签:面试官 实现 Spring 代理 切面 AOP SpringAOP 原理 动态

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程技术,它允许开发者在不改变现有代码的情况下,增加新的功能或行为,这些功能或行为被称为“切面”。

AOP 可以通过预编译方式和运行期动态代理的方式来实现,它的主要目的是降低业务逻辑的耦合性,提高程序的可重用性和开发效率。

AOP 常用于统一功能的处理,例如:事务管理、日志记录、权限检查等功能。

1.AOP优点分析

使用 AOP 的主要原因有以下几点:

  1. 模块化:通过将公共行为(如日志记录、事务管理)提取为独立的切面,可以使代码更加模块化,提高代码的可维护性和可读性。
  2. 减少重复代码:通过使用 AOP,可以将重复的代码(如日志记录、权限检查)提取到一个切面中,避免在多个地方重复编写相同的代码。
  3. 解耦:AOP 允许开发者将业务逻辑与横切关注点(如日志记录、事务管理)分离,从而降低业务逻辑的耦合性,提高程序的可重用性和可扩展性。

2.AOP技术实现

AOP 实现技术主要分为两大类:静态代理和动态代理。

  1. 静态代理:通过 AOP 框架提供的命令进行编译,从而在编译阶段生成 AOP 代理类。这种方式也被称为编译时增强。静态代理包括编译时编织和类加载时编织两种方式。
  2. 动态代理:在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。动态代理主要有两种实现方式:
    1. JDK 动态代理:JDK 动态代理要求被代理的类必须实现一个接口,它通过反射来接收被代理的类,并使用 InvocationHandler 接口和 Proxy 类实现代理。
    2. CGLIB 动态代理:CGLIB 则是一个代码生成的类库,它可以在运行时动态地生成某个类的子类,通过继承的方式实现代理。如果目标类没有实现接口,Spring AOP 会选择使用 CGLIB 来动态代理目标类。

3.AOP实现原理

Spring AOP(面向切面编程)的实现原理主要基于动态代理技术,它提供了对业务逻辑各个方面的关注点分离和模块化,使得非功能性需求(如日志记录、事务管理、安全检查等)可以集中管理和维护,而不是分散在各个业务模块中。

Spring AOP 实现原理的关键要点如下:

  1. 代理机制
    • JDK 动态代理:对于实现了接口的目标类,Spring AOP 默认使用 JDK 的 java.lang.reflect.Proxy 类来创建代理对象。代理对象会在运行时实现代理接口,并覆盖其中的方法,在方法调用前后执行切面逻辑(即通知,advice)。
    • CGLIB 动态代理:对于未实现接口的类,Spring AOP 会选择使用 CGLIB 库来生成代理对象。CGLIB 通过字节码技术创建目标类的子类,在子类中重写目标方法并在方法调用前后插入切面逻辑。
  2. 关键概念
    • 切面(Aspect):切面是一个包含了横切关注点声明的模块化单元,它可以有多个切入点和通知组成。
    • 切入点(Pointcut):切入点定义了匹配通知应该被织入的方法或方法执行点的规则表达式。
    • 通知(Advice):通知是在特定切入点处执行的代码片段,分为多种类型,如前置通知(Before advice)、后置通知(After returning advice)、异常后通知(After throwing advice)、最终通知(After (finally) advice)以及环绕通知(Around advice)。
  3. 织入(Weaving):织入是指将切面应用到目标对象来创建一个新的代理对象的过程。在 Spring AOP 中,织入发生在运行时,通过代理对象的方式实现。
  4. 代理工厂:Spring 内部通过 ProxyFactory 或相关的 AOP 基础设施(如 Advisor、AdvisorChainFactory 等)来创建和管理代理对象。
  5. 执行流程:当客户端通过代理对象调用目标方法时,代理对象会拦截这个调用,根据切面配置找到对应的通知,并按照通知类型的不同执行相应的增强逻辑。例如,如果是环绕通知,它会完全控制原始方法的调用过程,可以在调用前后插入自定义逻辑,甚至决定是否执行原方法。

通过上述方式,Spring AOP 巧妙地实现了对目标对象方法的拦截和增强,从而实现了面向切面编程的功能。

课后思考

Spring 动态代理失效的场景有哪些?Spring Boot 动态代理默认实现是 JDK 动态代理还是 CGLIB?怎么证明?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

标签:面试官,实现,Spring,代理,切面,AOP,SpringAOP,原理,动态
From: https://www.cnblogs.com/vipstone/p/18053514

相关文章

  • git原理性概念
    参考资料近期学习git内部概念及原理,为了加强效果和日后回忆,还是写了这篇笔记进行输出。参考资料如下:这才是真正的Git——Git内部原理-LZANE|李泽帆(靓仔)《VersionControlwithgit》实验环境:unbuntu18objects(blobstreecommitstag)&hashgit里的object有四种:tree......
  • BOSHIDA DC电源模块的工作原理及应用
    BOSHIDADC电源模块的工作原理及应用DC电源模块是一种常见的电子元件,它具有将交流电转换为直流电的功能。在很多电子设备中,尤其是需要稳定的直流电源供应的设备中,DC电源模块被广泛应用。 DC电源模块的工作原理可以简单描述如下:将输入的交流电转换为直流电。首先,交流电输入到......
  • vue2响应式原理
    Vue.js是一个流行的JavaScript前端框架,它的核心特性之一就是响应式数据绑定。Vue.js2.x版本的响应式原理主要基于Object.defineProperty函数来实现。Vue.js的响应式原理大致可以描述为以下几个步骤:数据劫持:当Vue实例创建时,Vue会遍历data选项中的属性,并使用Obje......
  • 在Docker中,资源限制原理是什么?
    在Docker中,资源限制主要是通过Linux内核的ControlGroups(cgroups)和Namespaces技术来实现的。1.ControlGroups(cgroups)cgroups是Linux内核的一个特性,它提供了一种机制来限制、记录、隔离进程组使用的物理资源(如CPU、内存、磁盘I/O等)。当Docker创建一个容器时,它会为该......
  • 面试官:集合使用时应该注意哪些问题?我:应该注意该注意的问题!
    写在开头面试官:“小伙子,java的集合学过吗?”我:“肯定学过呀!”,这时候的我自信满满,手撕集合八股文嘛,早已背的滚瓜烂熟了呀。面试官:“那你来讲讲集合使用时,应该注意哪些问题吧”我:“额,这,我想想哈。”,什么!这面试官不按套路出牌,上来就问注意事项,打我一个措手不及啊。我:“嗯~,我觉得......
  • 计算机基础知识问答:计算机组成原理篇
    冯诺依曼机的基本思想:冯诺依曼机的基本思想主要包括以下几点:存储程序:计算机内部设置存储器,程序和数据统一存放在存储器中,指令和数据均用二进制数表示。程序控制:计算机执行程序时,无需人工干预,能自动、连续地执行程序,并得到预期的结果。二进制运算:计算机内部以二进制......
  • unhide 是一款强大的取证工具,主要用于查找和发现被隐藏的进程、TCP/UDP端口以及其他隐
    unhide是一款强大的取证工具,主要用于查找和发现被隐藏的进程、TCP/UDP端口以及其他隐藏技术。其基本技术原理如下:ROOTKIT和LKM:ROOTKIT(RootKit)是一种恶意软件,常用于隐藏恶意活动和进程。它通过修改操作系统的核心组件和内核模块(LinuxKernelModule,LKM)来实现对系统的隐匿。u......
  • 对于Windows系统的入侵痕迹溯源,以下是一些基础技术原理
    对于Windows系统的入侵痕迹溯源,以下是一些基础技术原理:日志分析:通过分析Windows系统的各类日志,包括安全日志、事件日志、系统日志等,可以追踪潜在的入侵行为和异常活动。关注登录记录、权限变更、文件访问等操作,以发现不明示的活动。网络流量分析:监控网络流量,并分析与Windows......
  • Windows 系统日志是记录操作系统活动的重要组成部分,对于入侵排查和溯源来说,分析系统日
    Windows系统日志是记录操作系统活动的重要组成部分,对于入侵排查和溯源来说,分析系统日志是非常关键的一步。以下是针对Windows系统日志分析和溯源的基础技术原理:事件日志:Windows操作系统生成多个类型的事件日志,包括应用程序日志、安全日志和系统日志。了解不同类型的事件日......
  • Volatile关键字原理
    转载请标明:https://www.cnblogs.com/tangZH/p/15113505.html一、如果一个变量被volatile关键字修饰,那么所有线程都是可见的。所谓可见就是,当一条线程修改了这个变量值,新值对于其他线程来时是立即可见的; 而普通变量不能做到这一点。 1、现在计算机缓存架构:  CPU与内存之......