SpringAOP 面试题
Posted FearAndGreed
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAOP 面试题相关的知识,希望对你有一定的参考价值。
Created By Cofson in 2021-05-23 19:38:17
SpringAOP 面试题
AOP理解及核心概念
AOPOP,面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect)。
减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
可用于权限认证、日志、事务处理。
切面(Aspect)
被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。
连接点(Join point)
指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。
通知(Advice)
在切面的某个特定的连接点(Join point)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。
切入点(Pointcut)
切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add、search。
引入(Introduction)
(也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。
目标对象(Target Object)
被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。
织入(Weaving)
织入指把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:
-
编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器;
-
类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码;
-
运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术。
静态代理(AspectJ)和动态代理(Spring AOP)
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
静态代理与动态代理区别如下图所示,重点掌握织入时机、织入范围的区别,即第3、4、5条区别
Spring AOP动态代理的两种方式(JDK和CGLIB)
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。
JDK动态代理只提供接口的代理,不支持类的代理。
核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;
接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。
CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
参考阅读
-- Java 动态代理作用是什么(非常重要)
-- Spring AOP的实现原理(非常重要)
两种动态代理方式主要区别
Jdk代理:基于接口的代理,一定是基于接口,会生成目标对象的接口的子对象。
Cglib代理:基于类的代理,不需要基于接口,会生成目标对象的子对象,但无法代理final修饰的类/方法。
开启动态代理
-
注解@EnableAspectJAutoProxy开启代理
-
proxyTargetClass默认为false,表示使用jdk动态代理织入增强,true表示使用Cglib动态代理技术织入增强
-
如果proxyTargetClass默认为false,但目标类没有声明接口,Spring aop还是会使用Cglib动态代理,也就是说非接口的类要生成代理都用Cglib
切点指示器
以上是关于SpringAOP 面试题的主要内容,如果未能解决你的问题,请参考以下文章