【Spring面试】七、AOP相关

news2025/1/23 17:51:55

文章目录

  • Q1、什么是AOP?能做什么?
  • Q2、解释下Spring AOP中常见的概念名词
  • Q3、Spring AOP的通知有哪些类型?
  • Q4、Spring AOP和AspectJ AOP有什么区别?
  • Q5、JDK动态代理和CGLIB动态代理的区别是什么?
  • Q6、JavaConfig方式如何启用AOP?如何强制使用cglib?
  • Q7、介绍下AOP有几种实现方式?
  • Q8、什么情况下AOP会失效?怎么解决?
  • Q9、Spring的AOP是在哪里创建的动态代理?
  • Q10、描述Spring AOP完整的实现流程?

Q1、什么是AOP?能做什么?

答案:

AOP(Aspect Oriented Programming),即面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑(如日志采集),抽取并封装形成切面(Aspect)后对已有方法或对象做一个增强,减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。

AOPOOP

AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想,OOP面向对象编程,针对的是业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清浙高效的逻单元划分。而AOP作为面向对象的一种补充,则是针对业务处理过程中的切面进行提取,已达到业务代码和公共行为代码之间低耦合性的隔离效果,这两种设计思想在目标上有着本质的差异。

Q2、解释下Spring AOP中常见的概念名词

答案:

  • 切面:Aspect,在Spring AOP中就是切面类,切面类中管理者切点和通知
  • 连接点:Join Point,在Spring AOP中就是被增强的业务方法,广义的来说,是程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等
  • 通知:Advice,就是需要增强到业务方法中的公共代码,有五种类型:前置通知、后置通知、异常通知、环绕通知、返回通知
  • 切点:PoinCut,即要增强哪些方法,哪些不需要增强,结合切点表达式来实现匹配
  • 目标对象:Target Object,被增强的那个对象
  • 织入:Weaving,在Spring AOP中就是为目标对象创建动态代理的过程。在Aspectj中比较繁琐,Spring不涉及。

在这里插入图片描述

Q3、Spring AOP的通知有哪些类型?

答案:

在AOP术语中,在的某个特定的连接点上执行的动作。Spring切面可以应用5种类型的通知:

  • 前置通知 (Before):在目标方法被调用之前调用通知功能
  • 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么
  • 返回通知 (After-returning ) :在目标方法成功执行之后调用通知
  • 异常通知 (After-throwing):在目标方法抛出异常后调用通知
  • 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

关于执行顺序:

在这里插入图片描述

Q4、Spring AOP和AspectJ AOP有什么区别?

先说下二者的关系:当在Spring中要使用@Aspect、@Before等这些注解时,就需要添加AspectJ相关依赖:

<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.5</version>
</dependency>

Spring Aop需要 AspectJ 框架的支持,但只用到的AspectJ的切点解析和匹配(@Aspect、@Before..等这些注解都是由AspectJ 发明的),底层的实现则没有用AspectJ的静态织入。

答案:

  • AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ,动态代理则以Spring AOP为代表
  • Spring AOP基于动态代理实现(JDK提供的动态代理和CGLIB动态代理)
  • AspectJ是静态代理的增强,就是AOP框架会在编译阶段生成AOP代理类,在编译阶段就将增强代码织入到Java字节码(.class)中,因此也叫编译时增强
PS:关于织入时机,可了解下:

在这里插入图片描述

  • AspcetJ是AOP的完全解决方案,能做很多Spring AOP不能做的事,Spring AOP则只专注于解决企业级开发中常见的AOP需求
  • AspectJ在实际代码运行前就完成了织入,而Spring AOP是Spring容器启动时才生成需要的代理对象,在启动上相比AspectJ会有一点性能损失

Q5、JDK动态代理和CGLIB动态代理的区别是什么?

答案:

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:

JDK动态代理:
  • JDK动态代理只提供接口的代理,不支持类的代理
  • JDK会在运行时为目标类生成一个动态代理类$proxy*.class
  • 该代理类是实现了目标类接口, 并且代理类会实现接口所有的方法,并加增强代码
  • 调用时 通过代理类先去调用处理类进行增强,再通过反射的方式进行调用目标方法,从而实现AOP
CGLIB动态代理:

如果代理类没有实现 接口,那么Spring AOP会选择使用CGLIB来动态代理目标:

  • CGLIB的底层是通过ASM在运行时动态的生成目标类的一个子类(会生成多个,还有其他相关类,主要是为增强调用时效率)
  • 并且会重写父类所有的方法增强代码
  • 调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用原目标方法,从而实现AOP

需要注意的是:

  • CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为fnal,那么它是无法使用CGLIB做动态代理的
  • CGLIB 除了生成目标子类代理类,还有一个FasiClass(路由类),可以(但不是必须)让本类方法调用进行增强,而不会像Jdk代理那样本类方法调用增强会失效

最后,关于JDK动态代理和CGLIB动态代理的性能问题:

  • jdk动态代理生成类速度快,调用慢,cglib生成类速度慢,但后续调用快
  • 在老版本中,CGLIB速度优于JDK动态代理
  • 在新版本(JDK7、JDK8…),JDK动态代理性能要比CGLIB好20%左右,总之就是看版本

Q6、JavaConfig方式如何启用AOP?如何强制使用cglib?

答案:

  • 首先需要添加Spring AOP和AspectJ的依赖
  • 其次加@EnableAspectJAutoProxy注解

@EnableAspectJAutoProxy注解有两个属性:

  • proxyTargetClass = true ,即强制使用cglib动态代理
  • exposeProxy = true, 即在线程中暴露代理对象

PS:所谓在线程中暴露代理对象,就是为true时,可以拿到当前的代理对象,这样就可以防止本类方法不会增强的问题。

//拿到当前的代理对象,记得再转型为本类
AopContext.currentProxy()
//用法:本类中的方法调用其他方法
( (本类)AopContext.currentProxy() ).本类中的其他方法();

Q7、介绍下AOP有几种实现方式?

答案:

  • 第一种:Spring1.2,基于接口来实现,也是现在注解背后的逻辑

在这里插入图片描述

在这里插入图片描述

  • 第二种:Spring2.0的schema-based配置,使用xml以及<aop>标签

在这里插入图片描述

  • 第三种:Spring2.0的@AspectJ配置,基于注解实现
  • 第四种:以上三种是Spring AOP的实现,也可以直接用AspectJ框架,这时和Spring没有关系了,静态织入+AspectJ单独编译

Q8、什么情况下AOP会失效?怎么解决?

答案:

内部调用不会触发AOP,即同一个类里的方法A内部调用方法B,则执行方法A时,中间的方法B不会被增强。

public class AopTest{

	public void add(){
	}
	
	public void mod(){
		this.add();  //这里不是增强的add方法
	}

}

在这里插入图片描述
解决思路是必须走代理,用代理对象去调用

在这里插入图片描述
想拿到动态代理对象,有两种方式:

  • 方式一:在这个类里,注入对象自身
public class AopTest{

	@Autowired
	AopTest aopTest;

	public void add(){
	}
	
	public void mod(){
		aopTest.add();  //此时是增强的add方法
	}

}
  • 方式二:设置暴露当前代理对象到本地线程,这样AopContext.currentProxy()就可以拿到正在调用的代理对象
@EnableAspectJAutoProxy(exposeProxy = true)
//....
public class AopTest{

	public void add(){
	}
	
	public void mod(){
		((AopTest) AopContext.currentProxy()).add();   
		//这个封装的静态方法currentProxy,底层在操作ThreadLocal
	}

}

最后补充下其余失效场景:(多为使用不当)

  • 方法是private修饰,需要改为public
  • 目标类没有配置为Bean,Spring是为Bean去创建动态代理

Q9、Spring的AOP是在哪里创建的动态代理?

答案:

  • 正常的Bean在Bean的生命周期初始化之后,通过Bean的后置处理器来创建aop(BeanPostProcessor.postProcessAfterInitialization)

在这里插入图片描述

  • 还有一种特殊的情况,即在Bean的生命周期的属性注入阶段,当出现循环依赖,也会为循环依赖的Bean创建aop(MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition)

Q10、描述Spring AOP完整的实现流程?

答案:

以JavaConfig为例(xml实现AOP的方式跳过):@EnableAspectJAutoProxy会通过@Import注册一个Bean的后置处理器来处理AOP,然后:

在这里插入图片描述

  • 解析切面:在创建Bean之前,调用Bean的后置处理器去解析切面,一个通知解析成一个advisor对象,这个对象中包含着通知和被增强的pointcut

在这里插入图片描述

  • 创建动态代理:正常的Bean初始化后调用BeanPostProcessor拿到之前缓存的advisor,再通过advisor里的pointcut来判断当前Bean是否被切点表达式匹配,如果匹配,就会为Bean创建动态代理

在这里插入图片描述

  • 调用:通过之前创建的动态代理,调用方法执行增强,通过调用链设计模式依次调用各个类型的通知方法

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地docker注册证书docker login连接到harbor仓库、利用shell脚本将大量镜像pull、tag、push到私有harbor仓库

1. 本地docker注册证书docker login连接到harbor仓库&#xff1a; 我们使用docker login/push/pull去与Harbor打交道&#xff0c;上传下载镜像等。 但是可能会出现x509: certificate signed by unknown authority之类的错误。 [roottest01 harbor.dev]# docker login harbor.d…

Nacos server 2.2.3 功能参数配置

1、Nacos server下载 登录网址Releases alibaba/nacos GitHub&#xff0c;进入下载页面&#xff0c;显示如下&#xff1a; 选择“nacos-server-2.2.3.zip”版本 解压缩&#xff0c;目录文件如下图所示&#xff1a; 配置文件位于“conf”目录下&#xff0c;名称为“applicat…

天津DV证书和OV证书的区别

SSL数字证书是一种安全协议&#xff0c;用于在网络传输过程中保护敏感信息&#xff0c;如信用卡号、用户名、密码等。它通过使用公钥和私钥来进行加密和解密&#xff0c;确保数据传输的机密性和完整性。 SSL数字证书的主要作用是在客户端和服务器之间建立安全的连接&#xff0c…

HarmonyOS/OpenHarmony应用开发-DevEco Studio帮助快速入门的使用

DevEco Studio内置有帮助中心&#xff0c;初学HarmonyOS 及OpenHarmony应用、元服务的开发者&#xff0c;通过内置的帮助中去系统的学习相关内容&#xff0c;是边练边学&#xff0c;快速上手的最佳方式。 一、帮助 二、快速开始 三、HarmonyOS应用、元服务开发相关 四、OpenHa…

Idea汉化

下载IDEA官方插件包https://plugins.jetbrains.com/ 输入关键子"chinese"查询汉化包 本地安装

银河麒麟arm服务器设置网卡开机自启

桌面右键打开系统终端 查看网络信息 输入命令&#xff1a; ip a 比如我们要设置eno3网卡 切换到指定目录 输入命令 cd /etc/sysconfig/network-scripts 查看该目录下的文件 输入命令ls 编辑指定网卡信息 vi *eno3 设置onboot项的值为yes &#xff0c;重庆服务器即可 …

Flutter框架和原理剖析

Flutter是Google推出并开源的跨平台开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过Dart语言开发Flutter应用&#xff0c;一套代码同时运行在ios和Android平台。不仅如此&#xff0c;flutter还支持web、桌面、嵌入应用的开发。flutter提供了丰富的组件、接口&…

【论文阅读】 智能合约安全漏洞检测技术研究综述

一、SC安全漏洞事件 2016 年 6 月,黑客利用 DAO(decentralized autonomous organization)合约的可重入漏洞, 窃取了价值约 6000 万美元的以太币(即以太坊数字货币); 2017 年 7 月, 由于 Parity 多签名钱包合约的 Delegatecall 漏洞(parity multi-sig wallet delegatecall&#…

Gogs国内大佬开发的git私有服务

Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。 gogs官网&#xff1a;https://gogs.io/ github地址&#xff1a;https://github.com/gogs/gogs/tree/main/docker docker安装gogs服务 docker pull gogs/gogs 启动gogs容器 docker run --namegogs -…

[NLP] LLM---训练一个中文LLama2的步骤

一 数据集 【Awesome-Chinese-LLM中文数据集】 【awesome-instruction-dataset】【awesome-instruction-datasets】【LLaMA-Efficient-Tuning-数据集】Wiki中文百科&#xff08;25w词条&#xff09;wikipedia-cn-20230720-filteredBaiduBaiKe&#xff08;563w词条&#xff09; …

气传导耳机品牌排行榜前十名,性能出色的气传导耳机分享

​气传导耳机在运动、户外、办公等场景中具有独特的优势。然而&#xff0c;面对市场上琳琅满目的气传导耳机产品&#xff0c;很多用户不知如何下手。接下来&#xff0c;我将推荐市面上热销火爆&#xff0c;并性能出色、性价比高的气传导耳机给大家&#xff0c;希望大家都能选到…

Kubernetes configmap + Secret

secret 参考文档&#xff1a;使用 Secret 安全地分发凭证 | Kubernetes 使用 Secret 安全地分发凭证 创建 Secret&#xff1a; &#xff08;secret.yaml&#xff09; apiVersion: v1 kind: Secret metadata:name: test-secret data:username: bXktYXBwpassword: Mzk1MjgkdmR…

Linux Day13 ---信号量

一、信号量 1.1 一些概念 用来管理对资源的访问 一个特殊的变量&#xff0c;只允许对它进行等待(wait)和发送信号(signal),代表可用资源个数&#xff0c; 取0,1 二值信号量 取 3,5 计数信号量 p操作&#xff1a;原子减一&#xff0c;代表获取资源&#xff0c;可能阻塞 v…

【共建开源】手把手教你贡献一个 SeaTunnel PR,超级详细教程!

Apache SeaTunnel是一个非常易于使用的、超高性能的分布式数据集成平台&#xff0c;支持海量数据的实时同步。每天可稳定高效同步数百亿数据&#xff0c;已被近百家企业投入生产使用。 现在的版本不支持通过jtds的方式链接sqlserver&#xff0c;我们来自己写代码来实现它&…

Spark 框架概述

目录 一、Spark 是什么 1.1 统一分析引擎&#xff1f; 二、Spark 风雨十年 ​三、Spark VS Hadoop(MapReduce) 3.1 面试题&#xff1a;Hadoop 的基于进程的计算和 Spark 基于线程方式优缺点&#xff1f; 四、Spark 四大特点 ​4.1 速度快 4.2 易于使用 4.3 通用性…

使用jib-maven-plugin插件构建镜像并推送至私服Harbor

jib-maven-plugin 插件配置 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apa…

19-springcloud(下)

一 分布式配置中心 1 Spring Cloud Config 分布式系统面临问题 在分布式系统中&#xff0c;由于服务数量巨多&#xff0c;为了方便服务配置文件统一管理&#xff0c;实时更新&#xff0c;所以需要分布式配置中心组件。 什么是Spring Cloud Config Spring Cloud Config项目是…

20230913java面经整理

1.hashmap为什么重写hashcode必须重写equals&#xff1f;不重写hashcode&#xff1f; hashcode判断对象存放的索引值&#xff0c;equals判断相同索引下对象是否相同&#xff0c;不同则存放&#xff08;链表&#xff09; hashcode提升查询效率&#xff0c;通过哈希计算&#xf…

【【萌新编写riscV之计算机体系结构之CPU 总二】】

萌新编写riscV之计算机体系结构之CPU 总二&#xff08;我水平太差总结不到位&#xff09; 在学习完软件是如何使用之后 我们接下来要面对的问题是 整个程序是如何运转的这一基本逻辑 中央处理器(central processing unit&#xff0c;CPU)的任务就是负责提取程序指令&#xff0…

2023年9月16日(星期六)骑行新海晏村

2023年9月16日 (星期六)&#xff1a;骑行新海晏村&#xff0c;早8:30到9:00&#xff0c; 大观楼门囗集合&#xff0c;9:30准时出发 【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点: 大观楼门囗集合&#xff0c;家住东&#xff0c;南&#xff0c…