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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 面试官:说说SpringAOP实现原理?

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

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

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

1.AOP优点分析

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

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

    2.AOP技术实现

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

  4. 静态代理:通过 AOP 框架提供的命令进行编译,从而在编译阶段生成 AOP 代理类。这种方式也被称为编译时增强。静态代理包括编译时编织和类加载时编织两种方式。

  5. 动态代理:在运行时在内存中“临时”生成 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、设计模式、消息队列等模块。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
存储 算法 Java
【Java集合类面试八】、 介绍一下HashMap底层的实现原理
HashMap基于hash算法,通过put和get方法存储和获取对象,自动调整容量,并在碰撞时用链表或红黑树组织元素以优化性能。
|
2月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
104 3
|
26天前
|
存储 算法 安全
HashMap常见面试题(超全面):实现原理、扩容机制、链表何时升级为红黑树、死循环
HashMap常见面试题:红黑树、散列表,HashMap实现原理、扩容机制,HashMap的jd1.7与jdk1.8有什么区别,寻址算法、链表何时升级为红黑树、死循环
|
27天前
|
存储 安全 Java
面试题:再谈Synchronized实现原理!
面试题:再谈Synchronized实现原理!
|
3月前
|
Java
【多线程面试题十六】、谈谈ReentrantLock的实现原理
这篇文章解释了`ReentrantLock`的实现原理,它基于Java中的`AbstractQueuedSynchronizer`(AQS)构建,通过重写AQS的`tryAcquire`和`tryRelease`方法来实现锁的获取与释放,并详细描述了AQS内部的同步队列和条件队列以及独占模式的工作原理。
【多线程面试题十六】、谈谈ReentrantLock的实现原理
|
3月前
|
网络协议 Oracle Java
【IO面试题 三】、说说NIO的实现原理
Java NIO的实现原理基于Channel、Buffer和Selector,支持从Channel读取数据到Buffer以及从Buffer写入数据到Channel,并通过Selector实现单线程多Channel的事件驱动IO操作。
【IO面试题 三】、说说NIO的实现原理
|
6月前
|
存储 缓存 安全
面试官:说说volatile底层实现原理?
面试官:说说volatile底层实现原理?
498 5
面试官:说说volatile底层实现原理?
|
3月前
|
缓存 安全 Java
面试官:说说volatile应用和实现原理?
面试官:说说volatile应用和实现原理?
44 1
|
3月前
|
设计模式 消息中间件 安全
面试官:说说读写锁的实现原理?
面试官:说说读写锁的实现原理?
60 1
|
3月前
|
Java 调度
【多线程面试题十四】、说一说synchronized的底层实现原理
这篇文章解释了Java中的`synchronized`关键字的底层实现原理,包括它在代码块和方法同步中的实现方式,以及通过`monitorenter`和`monitorexit`指令以及`ACC_SYNCHRONIZED`访问标志来控制线程同步和锁的获取与释放。