Foutin

SpringIOC和AOP自实现

长到这么大,我说不出来我最爱的一部电影,说不出来我最爱的一首歌,说不出来我最爱的一个人。时常觉得人生其实没那么有趣,偶尔也会质疑活着的意义,所有来自于书上和别人口中的意义都不曾说服过我。但今天突然觉得,大概人生最大的意义就是用余生去找到那些最爱吧。

Spring AOP常见概念

AOP 是 Spring 独有的概念吗?

不是,除了Spring AOP,AOP 常见的实现还有:

  • Aspectj
  • Guice AOP
  • Jboss AOP

AOP Alliance 是什么, 为什么 Spring AOP 需要 aopalliance.jar ?

  • AOP Alliance 是AOP的接口标准,定义了 AOP 中的基础概念(Advice、CutPoint、Advisor等),目标是为各种AOP实现提供统一的接口,本身并不是一种 AOP 的实现。
  • Spring AOP, GUICE等都采用了AOP Alliance中定义的接口,因而这些lib都需要依赖 aopalliance.jar。
  • Spring 4.3之后内置了AOP Alliance接口,不再需要单独的aopalliance.jar。

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或者cglib实现代理类生成。对于有实现接口的类使用JDK Proxy,对于无接口的则是用cglib.通过

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

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

JDK Proxy 和 cglib 代理类生成什么区别?

JDK Proxy只适用于类实现了接口的情况.生成的代理类实现了原类的接口,但和原类没有继承关系.

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

Spring-aspects 又是什么鬼

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

为什么spring-aspects 还需要 aspectjweaver.jar才能工作

Spring-aspects 实现XML配置解析和类似 Aspectj 注解方式的时候,借用了 aspectjweaver.jar 中定义的一些annotation 和 class,然而其并不使用 Aspectj 的字节码织入功能。

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

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

Spring 3.1 之前 spring-aspects 对 aspectjweaver 的依赖还是 optional 的,需要自己再添加依赖;Sprint 3.2 之后 依赖取消了 optional 设置,可以不用自己添加了。

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------