Spring全家桶面试题(一)之Spring Framework(六)

五、Spring AOP

46. 什么是AOP、能做什么

AOP(Aspect-Oriented Programming),一般称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

可用于权限认证、日志、事务处理等。

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

47. 解释一下Spring AOP里面的几个名词

(1)切面(Aspect): 在Spring Aop指定就是“切面类” ,切面类会管理着切点、通知。
(2)连接点(Join point): 指定就是被增强的业务方法
(3)通知(Advice): 就是需要增加到业务方法中的公共代码, 通知有很多种类型分别可以在需要增加的业务方法
不同位置进行执行(前置通知、后置通知、异常通知、返回通知、环绕通知)
(4)切点(Pointcut): 由他决定哪些方法需要增强、哪些不需要增强, 切点表达式是一个具体的实现
(5)目标对象(Target Object): 指定是增强的对象
(6)织入(Weaving) : spring aop用的织入方式:动态代理。 就是为目标对象创建动态代理的过程就叫织入。(将通知切入连接点的过程)

48. Spring通知有哪些类型?

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

  1. 前置通知(Before):在目标方法被调用之前调用通知功能;
  2. 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
  3. 返回通知(After-returning ):在目标方法成功执行之后调用通知;
    图灵课堂
  4. 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  5. 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
    执行顺序:
    Spring全家桶面试题(一)之Spring Framework(六)_第1张图片
    Spring在5.2.7之后就改变的advice 的执行顺序。
    1、正常执行:@Before­­­>方法­­­­>@AfterReturning­­­>@After
    2、异常执行:@Before­­­>方法­­­­>@AfterThrowing­­­>@After

49. Spring AOP and AspectJ AOP 有什么区别?

1. Spring AOP和AspectJ AOP的关系

当在Spring中要使用@Aspect、@Before.等这些注解的时候, 就需要添加AspectJ相关依赖

<dependency>
	<groupId>org.aspectjgroupId>
	<artifactId>aspectjweaverartifactId>
	<version>1.9.5version>
dependency>

Spring Aop提供了 AspectJ 的支持,但只用到的AspectJ的切点解析和匹配,@Aspect、@Before.等这些注解
都是由AspectJ 发明的。
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以
Spring AOP为代表。

2. Spring AOP和AspectJ AOP的区别:

Spring AOP使用的动态代理,它基于动态代理来实现。默认地,如果使用接口的,用 JDK 提供的动态代理实现,
如果没有接口,使用 CGLIB 实现。
AspectJ静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增
强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
属于静态织入,它是通过修改代码来实现的,它的织入时机可以是:

  • Compile-time weaving:编译期织入
  • Post-compile weaving:编译后织入
  • Load-time weaving:指的是在加载类的时候进行织入

AspectJ 出身也是名门,来自于 Eclipse 基金会
AspectJ 能干很多 Spring AOP 干不了的事情,它是 AOP 编程的完全解决方案。Spring AOP 致力于解决的是企业级开发中最普遍的 AOP 需求(方法织入),而不是力求成为一个像 AspectJ 一样的 AOP 编程完全解决方案。

因为 AspectJ 在实际代码运行前完成了织入,所以大家会说它生成的类是没有额外运行时开销的。很多人会对比 Spring AOP 和 AspectJ 的性能,Spring AOP 是基于代理实现的,在容器启动的时候需要生成代理实例,在方法调用上也会增加栈的深度,使得 Spring AOP 的性能不如 AspectJ 那么好。

50. JDK动态代理和CGLIB动态代理的区别

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

  • JDK动态代理只提供接口的代理,不支持类的代理

    • JDK会在运行时为目标类生成一个 动态代理类$proxy*.class
    • 该代理类是实现了目标类接口, 并且代理类会实现接口所有的方法
    • 调用时,通过代理类先去调用处理类(在处理类写增强代码)进行增强,再通过反射的方式进行调用目标方法,从而
      实现AOP
  • 如果代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类

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

注意:

  1. CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
  2. CGLIB 除了生成目标子类代理类,还有一个FastClass(路由类),可以(但不是必须)让本类方法调用进行增强,而不会像jdk代理那样本类方法调用增强会失效。(在Spring AOP中为了保持跟JDK动态代理效果一致,因此并没有用到让本类方法增强的功能)

很多人会对比 JDK和Cglib的性能,jdk动态代理生成类速度快,调用慢,cglib生成类速度慢,但后续调用
快,在老版本CGLIB的速度是JDK速度的10倍左右, 但是实际上JDK的速度在版本升级的时候每次都提高很多性能,而
CGLIB仍止步不前.

51.JavaConfig方式如何启用AOP?如何强制使用cglib?

@EnableAspectJAutoProxy
(proxyTargetClass = true) //强制CGLIB
(exposeProxy = true) //在线程中暴露代理对象

获取当前线程的动态代理对象,防止调用本类的方法,不会进行增强(cglib本身就实现了,这个主要用于JDK)

public int mod(int numA,int numB){
	System.out.println("执行目标方法:mod");
	//获取当前线程的动态代理对象,防止调用本类的方法,不会进行增强(cglib本身就实现了,这个主要用于JDK)
	int retVal=((Caculate)AopContext.currentProxy()).add(numA,numB);
	int retVal=this.add(numA,numB);
	return retVal%numA;
}

52.介绍AOP有几种实现方式

  • Spring 1.2 基于接口的配置:最早的 Spring AOP 是完全基于几个接口的,想看源码的同学可以从这里起步。
  • Spring 2.0 schema-based 配置:Spring 2.0 以后使用 XML 的方式来配置,使用 命名空间
  • Spring 2.0 @AspectJ 配置:使用注解的方式来配置,这种方式感觉是最方便的,还有,这里虽然叫做 @AspectJ,但是这个和 AspectJ 其实没啥关系。
  • AspectJ 方式,这种方式其实和Spring没有关系,采用AspectJ 进行动态织入的方式实现AOP,需要用AspectJ 单独编译。

基于接口的配置
写一个类实现前置通知的接口
Spring全家桶面试题(一)之Spring Framework(六)_第2张图片
Spring全家桶面试题(一)之Spring Framework(六)_第3张图片
接口的方式,需要自己手动创建顾问,配置通知和切入点
Spring全家桶面试题(一)之Spring Framework(六)_第4张图片
基于注解和XML的配置
参考https://blog.csdn.net/shaohe18362202126/article/details/81952082?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165527248816781818740462%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165527248816781818740462&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-81952082-null-null.nonecase&utm_term=AOP%E6%9C%89%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F&spm=1018.2226.3001.4450

你可能感兴趣的:(#,面试笔试,后端,spring,java,面试)