- 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
AOP面试题及答案(实战导向版)
一、基础概念题
为什么项目里需要用AOP?举个你实际用过的场景
答:因为AOP能解决“横切逻辑冗余”问题——比如日志记录、权限校验、事务控制这些功能,如果写在每个业务方法里,会重复且难维护。
我之前在订单系统里用AOP做过接口日志:所有订单相关接口(创建、支付、取消)都要记录请求参数、响应结果和耗时,用AOP定义一个切面拦截这些接口,统一处理日志,业务代码里完全不用管日志逻辑,后续要改日志格式也只改切面就行。
AOP里的“切面”“切点”“通知”分别对应什么?用刚才的日志场景举例说明
答:
切面(Aspect):就是“横切逻辑+拦截规则”的集合,比如刚才的“日志处理逻辑+拦截订单接口的规则”,我当时写了个OrderLogAspect类,这就是切面;
切点(Pointcut):就是“拦截哪些方法”的规则,比如用表达式execution(*com.xxx.order.service.*Service.*(..))指定拦截订单服务层的所有方法,这就是切点;
通知(Advice):就是“横切逻辑的具体执行时机+代码”,比如日志要在方法执行前记录请求参数(@Before)、执行后记录响应(@AfterReturning),这两个带注解的方法就是通知。
二、SpringAOP实战题
SpringAOP和AspectJ有啥区别?你项目里用的是哪个?为什么
答:最核心的是底层实现和适用场景不一样:
SpringAOP是“动态代理”实现的,运行时才生成代理对象,轻量级,只支持方法级别的拦截,适合一般业务场景;
AspectJ是“编译期/类加载期织入”,编译时就把切面代码嵌入目标类,支持字段、构造器等更多拦截点,功能强但重,适合复杂切面需求(比如拦截静态方法)。
我项目里用的是SpringAOP,因为我们只需要拦截业务方法做日志、事务,SpringAOP足够用,而且不用额外引入AspectJ的编译插件,配置更简单。
SpringAOP里的环绕通知(@Around)和前置/后置通知有啥不一样?什么时候用环绕通知
答:最大区别是环绕通知能“控制方法执行流程”,前置/后置只能在方法前后加逻辑,没法阻止方法执行或修改返回值。
比如我之前做接口限流:用环绕通知拦截高频接口,先判断当前请求数是否超过阈值,如果超了直接返回“限流提示”,不执行原方法;如果没超才调用原方法。这种需要“先判断再决定是否执行方法”的场景,必须用环绕通知。
另外环绕通知还能获取方法的入参和返回值,比如记录耗时的时候,在通知里用ProceedingJoinPoint.proceed()调用原方法,前后记录时间戳算差值,比前置+后置分开记录更准确。
SpringAOP的动态代理有两种:JDK动态代理和CGLIB,它们的区别是什么?Spring默认用哪个
答:区别主要在底层原理和适用条件:
JDK动态代理:必须基于接口,生成的代理类是目标类的“接口实现类”,底层用Proxy和InvocationHandler;
CGLIB:不用接口,生成的代理类是目标类的“子类”,底层用ASM字节码框架修改类结构,所以目标类不能是final(子类没法继承),方法也不能是final(子类没法重写)。
Spring默认规则:如果目标类有实现接口,就用JDK动态代理;如果没有接口(比如纯实现类),就用CGLIB。不过Spring5之后可以通过proxyTargetClass=true强制用CGLIB,不管有没有接口。
三、问题排查题
你遇到过AOP切面“不生效”的情况吗?怎么解决的
答:遇到过两次:
第一次是因为目标对象是自己new的,不是Spring容器管理的。比如我在Service里直接newOrderDao(),而AOP是基于Spring代理对象的,new出来的对象没被代理,切面自然不生效。后来改成用@Autowired注入OrderDao,就好了。
第二次是切点表达式写错了,把execution(*com.xxx.service.*.*(..))写成了com.xxx.services.*.*(多了个s),导致没匹配到目标方法。后来用Spring的@Pointcut注解配合日志,打印出匹配的方法名,才发现路径错了。
AOP能拦截静态方法吗?为什么
答:默认不行,特指SpringAOP。因为SpringAOP的动态代理(JDK/CGLIB)都是针对“实例方法”的:JDK代理要实现接口的实例方法,CGLIB要继承目标类的实例方法。而静态方法属于“类”,不是实例,
有哪些信誉好的足球投注网站
文档评论(0)