Spring AOP 问与答

本文深入解析了AOP技术,对比了SpringAOP与Aspectj的不同之处,并探讨了它们的实现原理,包括代理类生成方式及性能差异。

AOP的实现有哪些

AOP常见的实现有:

  • Spring AOP
  • Aspectj
  • Guice AOP
  • Jboss AOP

AOP Alliance 是什么, 为什么Spring AOP, G UI CE AOP等需要aopalliance.jar?

AOP Alliance定义了AOP中的基础概念,但它并不是一种AOP的实现,它的目标为各种AOP实现提供统一的接口.Spring AOP, GUICE等都采用了AOP Alliance中定义的接口.

Spring AOP 和 Aspectj的区别?

  • Spring AOP采用动态代理的方式,在运行期生成代理类来实现AOP,不修改原类的实现.
  • Aspectj 使用 编译 期字节码织入(weave)的方式,在编译的时候,直接修改类的字节码,把所定义的切面 代码 逻辑插入到目标类中。
  • Spring AOP可以对其它模块正常编译出的代码起作用,Aspectj 需要对其它模块使用acj重新编译
  • Spring AOP对于直接调用类内部的其它方法无效(需要获取对应的代理类来吊用),无法对定义为 final 的类生效(因为无法撑撑代理类,导致运行时异常)。Aspectj没有这些限制
  • Spring AOP使用 XML 配置 文件的方式定义切入点(CutPoint),Aspectj使用注解方式

  • 注: Aspectj 除了编译期静态织入的方式之外,也支持加载时动态织入修改类的字节码。

Spring AOP的代理类如何实现的?

Spring AOP使用JDK Proxy或者cg lib 实现代理类生成。对于有实现接口的类使用JDK Proxy,对于无接口的则是用cglib.通过

<aop:aspectj-autoproxy proxy-target-class="true"/>

指定proxy-target-class为true可强制使用cglib.

JDK Proxy 和 cglib什么区别?

JDK Proxy只适用于类实现了接口的情况,关系图:

Interface ----------> OriginClass |---------> ProxyClass

生成的代理类实现了原类的接口,但和原类没有继承关系.

cglib则是生成原来的子类,对于没有实现接口的情况也适用:

OriginClass --------> ProxyClass

cglib采用字节码生成的方式来在代理类中调用原类方法, JDK Proxy 则是使用反射调用,由于反射存在额外security check 的开销一集目前jvm jit对反射的内联支持不够好,JDK Proxy在性能上弱于cglib

spring -aspects 又是什么鬼

因为Spring AOP XML配置文件定义的方式太繁琐遭到吐槽,所以spring从Aspectj中吸收了其注解定义的方式。然而其实现依然是动态代理的方式,与aspectj 字节码织入的方式不同。

既然如此,那为什么spring-aspects 还需要aspectjrt.jar和aspectjweaver.jar才能工作?

确切的说,应该只需要aspectjweaver.jar, aspectjrt.jar是aspectjweaver.jar的子集。Spring-aspects 实现类似aspectj注解方式的时候,借用了aspectjweaver.jar中定义的一些annotation和class,然而其并不使用Aspectj的字节码织入功能。

spring-aspects 不能把这些所需的类定义抄一份过去吗,这样就不需要aspectjweaver.jar了

他们可以,但是他们偏不这样做

原文http ://www.udpwork.com/item/15373.html

 http://ju.outofmemory.cn/entry/251194

转载于:https://www.cnblogs.com/softidea/p/6222629.html

当被面试官询问Spring AOP(Aspect-Oriented Programming,面向切面编程)的原理时,可以从以下几个方面作答: ### 1. **AOP 的核心概念** - **横切关注点**:指跨越应用程序多个模块的功能需求,例如日志记录、权限校验、事务管理等。传统的OOP难以很好地将它们与业务逻辑分离。 - **连接点(Join Point)**:程序执行过程中能够插入切面的地点,在Spring AOP中主要是方法的执行时刻。 - **通知(Advice)**:定义了在特定的连接点上需要采取的动作。包括前置通知@Before、后置返回通知@AfterReturning、异常通知@AfterThrowing 和环绕通知 @Around 等形式。 - **切入点(Pointcut)**:描述一组连接点的集合,一般通过正则表达式或者注解等方式指定哪些地方会触发相应 Advice。 - **目标对象(Target Object)**:即将要被代理的对象实例,也就是那些需要加入额外功能的实际业务组件。 - **织入(Weaving)**:把 Aspect 合并到目标对象的过程叫做“织入”,可以在编译期、加载期或运行期间完成。 ### 2. **Spring AOP 实现机制** Spring AOP 主要是基于动态代理技术来实现: - **JDK 动态代理**:利用 `java.lang.reflect.Proxy` 类生成代理对象,只能对接口进行代理。它会在运行时创建实现了某些接口的新类,并覆盖原有方法以达到增强的目的。 ```java MyService proxyInstance = (MyService) Proxy.newProxyInstance( loader, interfaces, invocationHandler); ``` - **CGLIB 字节码增强**:如果目标类没有提供接口,则无法使用 JDK 动态代理。这时就会借助 CGLIB 创建子类并通过重写非 final 方法注入行为。此过程涉及到操纵字节数组构造新的 Class 文件并在内存中加载。 默认情况下,如果有接口优先选用 JDK Dynamic Proxy 方案;如果没有接口就回退至 Cglib。 ### 3. **工作流程简述** 假设有一个 service 层方法 add() 被标注了一个自定义注释 @LogExecutionTime ,那么大致步骤如下: 1. 定义一个切面类包含该 advice; 2. 使用 pointcut 表达式明确指出这个 annotation 可能出现的位置如 "execution(* com..service.*(..))"; 3. 根据是否满足条件决定调用哪个具体的 advices; 4. 最终形成带有附加职责的目标 method call chain; ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值