Spring面试之AOP相关问题

文章目录

  • 1 Spring AOP简介
    • 1.1 Spring AOP的描述
    • 1.2 关注点和横切关注点的区别
    • 1.3 AOP可用的实现
    • 1.4 AOP通知类型
    • 1.5 AOP代理的含义
    • 1.6 引介(Introduction)
    • 1.7 连接点(Joint Point)和切入点(Point cut)
      • 1.7.1 抽象定义
      • 1.7.2 深入理解
    • 1.8 织入

1 Spring AOP简介

1.1 Spring AOP的描述

Spring AOP(Aspect Oriented Programming,面向切面编程)是OOP(面向对象编程)的补充,它也提供了模块化。
在面向对象编程中,关键的单元是对象AOP的关键单元是切面,或者说关注点(可以简单地理解为程序中的独立模块)。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。一个横切关注点是一个可以影响到整个应用的关注点,而且应该被尽量地集中到代码的一个地方,例如事务管理、权限、日志、安全等。

AOP让你可以使用简单可插拔的配置,在实际逻辑执行之前、之后或周围动态添加横切关注点。这让代码在当下和将来都变得易于维护。如果是使用XML来使用切面的话,要添加或删除关注点,不用重新编译完整的源代码,而仅仅需要修改配置文件就可以了。

Spring AOP通过以下两种方式来使用。但是最广泛使用的方式是Spring AspectJ 注解风格(Spring AspectJ Annotation Style)

  • 使用AspectJ注解风格
  • 使用Spring XML配置风格

1.2 关注点和横切关注点的区别

关注点是我们想在应用的模块中实现的行为。
关注点可以被定义为:想实现以解决特定业务问题的方法。比如,在所有电子商务应用中,不同的关注点(或者模块)可能是库存管理、航运管理、用户管理等。

横切关注点是贯穿整个应用程序的关注点。像日志、安全和数据转换,它们在应用的每一个模块都是必须的,所以他们是一种横切关注点。

1.3 AOP可用的实现

基于Java的主要AOP实现有:

  • AspectJ
  • Spring AOP
  • JBoss AOP

1.4 AOP通知类型

通知(advice)是在程序中想要应用在其他模块中的横切关注点的实现
Advice主要有以下5种类型:

  • 前置通知(Before Advice):在连接点之前执行的Advice,不过除非它抛出异常,否则没有能力中断执行流。使用 @Before 注解使用这个Advice
  • 返回之后通知(After Retuning Advice):在连接点正常结束之后执行的Advice。例如,如果一个方法没有抛出异常正常返回。通过@AfterReturning关注使用它。
  • 抛出(异常)后执行通知(After Throwing Advice):如果一个方法通过抛出异常来退出的话,这个Advice就会被执行。通用 @AfterThrowing注解来使用。
  • 后置通知(After Advice):无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会执行在结束后执行这些Advice。通过@After注解使用。
  • 围绕通知(Around Advice):围绕连接点执行的Advice,就一个方法调用。这是最强大的Advice。通过 @Around 注解使用。

1.5 AOP代理的含义

代理是使用非常广泛的设计模式。简单来说,代理是一个看其他像另一个对象的对象,但它添加了一些特殊的功能
Spring AOP是基于代理实现的。AOP代理是一个由AOP框架创建的用于在运行时实现切面协议的对象。
Spring AOP默认为AOP代理使用标准的JDK动态代理。这使得任何接口(或者接口的集合)可以被代理。Spring AOP 也可以使用CGLIB代理。这对代理类而不是接口是必须的。
如果业务对象没有实现任何接口那么默认使用CGLIB

1.6 引介(Introduction)

引介让一个切面可以声明被通知的对象实现了任何他们没有真正实现的额外接口,而且为这些对象提供接口的实现
使用 @DeclareParents注解来生成一个引介。

1.7 连接点(Joint Point)和切入点(Point cut)

1.7.1 抽象定义

连接点:是程序执行的一个点,在应用执行过程中能够插入切面(Aspect)的一个点。这些点可以是调用方法时、甚至修改一个字段时
切入点:是指通知(Advice)所要织入(Weaving)的具体位置,是一个匹配连接点的断言或者表达式。Advice与切入点表达式相关联,并在切入点匹配的任何连接点处运行(比如,表达式 execution(* EmployeeManager.getEmployeeById(...)) 可以匹配 EmployeeManager 接口的 getEmployeeById())。由切入点表达式匹配的连接点的概念是AOP的核心。Spring默认使用 AspectJ 切入点表达式语言。

1.7.2 深入理解

连接点是一个虚拟概念,可以理解为所有满足切点扫描条件的所有的时机。
具体举个例子:比如开车经过一条高速公路,这条高速公路上有很多个出口(连接点),但是我们不会每个出口都会出去,只会选择我们需要的那个出口(切点)开出去。
简单可以理解为,每个出口都是连接点,但是我们使用的那个出口才是切点。每个应用有多个位置适合织入通知,这些位置都是连接点。但是只有我们选择的那个具体的位置才是切点。

1.8 织入

织入(weaving):说白了就是将切面切入点结合这是个逻辑过程,AOP有三种织入的方式:

  • 编译期织入,这要求使用特殊的Java编译器
  • 类装载期织入,这要求使用特殊的类装载器
  • 动态代理织入,在运行期为目标类添加增强生成子类的方式

这可以在编译时(比如使用AspectJ编译器)、加载时或者运行时完成,Spring AOP跟其他纯Java AOP框架一样,只在运行时执行织入。在协议上,AspectJ 框架支持编译时和加载时织入。
AspectJ 编译时织入是通过一个叫做ajc特殊的 AspectJ 编译器完成的。它可以将切面织入到Java源码文件中,然后输出织入后的二进制 class 文件。它也可以将切面织入你的编译后的 class 文件或者 Jar 文件。这个过程叫做后编译时织入(post-compile-time weaving)。在 Spring IOC 容器中声明你的类之前,你可以为它们运行编译时和后编译时织入。Spring 完全没有被包含到织入的过程中。
AspectJ加载时织入(load-time weaving, LTW)在目标类被类加载器加载到JVM时触发。对于一个被织入的对象,需要一个特殊的类加载器来增强目标类的字节码。AspectJSpring都提供了加载时织入器以为类加载添加加载时织入的能力。只需要简单的配置就可以打开这个加载时织入器。

你可能感兴趣的:(spring,spring,aop)