十一、什么是AOP?
参考回答:
在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程,也就是AOP。
AOP是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。
使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。
从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来的效果。
十二、AOP的重要概念有哪些?
参考回答:
(1) Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;
(2)Join point :连接点,也就是可以进行横向切入的位置;
(3)Advice :通知,切面在某个连接点执行的操作
(4)Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;
十三、简单介绍一下AOP 的实现原理
参考回答:
AOP分为静态AOP和动态AOP。
(1)静态AOP:静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。
(2)动态AOP:动态AOP是指将切面代码进行动态织入实现的AOP。
Spring的AOP为动态AOP,实现的技术原理是JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术) 。尽管实现技术不一样,但 都是基于代理模式 , 都是生成一个代理对象 。
十四、在Spring AOP中关注点和横切关注点有什么不同?
参考回答:
关注点是我们想在应用的模块中实现的行为。关注点可以被定义为:我们想实现以解决特定业务问题的方法。比如,在所有电子商务应用中,不同的关注点(或者模块)可能是库存管理、航运管理、用户管理等。
横切关注点是贯穿整个应用程序的关注点。像日志、安全和数据转换,它们在应用的每一个模块都是必须的,所以他们是一种横切关注点。
十五、Spring中有哪些不同的通知类型?
参考回答:
通知(advice)是你在你的程序中想要应用在其他模块中的横切关注点的实现。Advice主要有以下5种类型:
(1)前置通知(Before Advice): 在连接点之前执行的Advice,不过除非它抛出异常,否则没有能力中断执行流。使用@Before
注解使用这个Advice。
(2)返回之后通知(After Retuning Advice): 在连接点正常结束之后执行的Advice。例如,如果一个方法没有抛出异常正常返回。通过@AfterReturning
关注使用它。
(3)抛出(异常)后执行通知(After Throwing Advice): 如果一个方法通过抛出异常来退出的话,这个Advice就会被执行。通用@AfterThrowing
注解来使用。
(4)后置通知(After Advice): 无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会执行在结束后执行这些Advice。通过@After
注解使用。
(5)围绕通知(Around Advice): 围绕连接点执行的Advice,就你一个方法调用。这是最强大的Advice。通过 @Around
注解使用。
十六、Spring AOP 代理是什么?
参考回答:
代理是使用非常广泛的设计模式。简单来说,代理是一个看其他像另一个对象的对象,但它添加了一些特殊的功能。
Spring AOP是基于代理实现的。AOP 代理是一个由 AOP 框架创建的用于在运行时实现切面协议的对象。
Spring AOP默认为 AOP 代理使用标准的 JDK 动态代理。这使得任何接口(或者接口的集合)可以被代理。Spring AOP 也可以使用 CGLIB 代理。这对代理类而不是接口是必须的。
如果业务对象没有实现任何接口那么默认使用CGLIB。
十七、引介(Introduction)是什么?
参考回答:
引介让一个切面可以声明被通知的对象实现了任何他们没有真正实现的额外接口,而且为这些对象提供接口的实现。
可以使用 @DeclareParaents
注解来生成一个引介。
十八、连接点(Joint Point)和切入点(Point cut)是什么?
参考回答:
连接点是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。举例来说,所有定义在你的 EmpoyeeManager
接口中的方法都可以被认为是一个连接点,如果你在这些方法上使用横切关注点的话。
切入点(切入点)是一个匹配连接点的断言或者表达式。Advice 与切入点表达式相关联,并在切入点匹配的任何连接点处运行(比如,表达式 execution(* EmployeeManager.getEmployeeById(...))
可以匹配 EmployeeManager
接口的 getEmployeeById()
)。由切入点表达式匹配的连接点的概念是 AOP 的核心。Spring 默认使用 AspectJ 切入点表达式语言。
十九、什么是织入(weaving)?
参考回答:
织入是将切面与外部的应用类型或者类连接起来以创建通知对象(adviced object)的过程。这可以在编译时(比如使用 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时触发。对于一个被织入的对象,需要一个特殊的类加载器来增强目标类的字节码。
AspectJ 和 Spring 都提供了加载时织入器以为类加载添加加载时织入的能力。你只需要简单的配置就可以打开这个加载时织入器。
二十、SpringAOP中的动态代理主要两种方式?
参考回答:
(1)JDK动态代理:JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口,JDK动态代理的核心是InvocationHandler接口和Proxy类
(2)CGLIB动态代理:如果目标没有实现接口,那么SpringAOP会选择使用CGLIB来动态代理目标类,当然Spring也支持配置强制使用CGLIB动态来历。
CGLIB是一个代码生成的类库,可以在运行时动态的生成某个类的子类。
注意:CGLIB是通过集成的方式做的动态代理,因此如果某个类被标记为final,那么它无法使用CGLIB做动态代理