有人可以强调一下在 Spring 应用程序中使用 Spring AOP 和 AspectJ 的优缺点吗?
Spring-AOP Pros
它比 AspectJ 更容易使用,因为您不必使用 LTW (装载时织造装载时织造)或 AspectJ 编译器。
它使用代理模式和 Decorator
Spring-AOP Cons
AspectJ Pros
AspectJ 的缺点
段落 6.1.2-Spring AOP 功能和目标和章节 6.2 -@方面支持和 6.8-在 Spring 应用程序中使用 AspectJ应该特别有趣。
编译时编织可以提供性能方面的好处(在某些情况下) ,也可以提供 joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.
joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.
因为 SpringAOP 基本上是从容器创建的代理,所以您只能对 Spring bean 使用 AOP。而使用 AspectJ,您可以在所有 bean 中使用方面。另一个比较点是调试和代码行为的可预测性。在 Spring AOP 中,所有的工作都是由 Java 编译器预先形成的,方面是为 Spring bean 创建代理的一种非常酷的方式。在 AspectJ 中,如果修改代码,则需要进行更多的编译,并且很难理解方面的编织位置。甚至在 Spring 中关闭编织也更简单: 使用 Spring,您可以从配置中删除方面,然后重新启动,它就可以工作了。在 AspectJ 中,必须重新编译代码!
在装载时编织中,AspectJ 比 Spring 更灵活,因为 Spring 不支持 AspectJ 的所有选项。但是在我看来,如果您想要改变 bean 的创建过程,一个更好的方法是在工厂中管理自定义登录,而不是通过加载时编织方面来改变新操作符的行为。
我希望这个 AspectJ 和 Spring AOP 的全景图能够帮助您理解这两个魔药的区别
重要的是要考虑您的方面是否是关键任务,以及您的代码在哪里部署。SpringAOP 将意味着您依赖于加载时编织。这可能无法编织,根据我的经验,这意味着记录的错误可能存在,但不会阻止应用程序在没有方面代码 [我要补充的是,它可能有可能配置的方式,这是不是这种情况,但我个人没有意识到这一点的情况下运行]。编译时编织可以避免这种情况。
SpringAOP 是 Spring 框架的重要组成部分之一。在最基本的阶段,Spring 框架是基于 IoC 和 AOP 的。在春季学期的官方课程中,有一张幻灯片写道:
AOP 是框架中最重要的部分之一。
理解 Spring 中 AOP 是如何工作的关键点在于,当你用 Spring 编写一个 Aspect时,我们通过为你的对象构建一个代理来检测框架,如果你的 bean 实现了一个接口,我们就使用一个 JDKDynamicProxy,如果你的 bean 没有实现任何接口,我们就使用一个 CGLIB。请记住,如果您在版本3.2之前使用 Spring,那么您的类路径中必须有 cglib 2.2。从 Spring 3.2开始是没有用的,因为 cglib 2.2包含在内核中。
JDKDynamicProxy
Bean 创建时的框架将创建一个代理,该代理包装您的对象,并添加横切关注的职责,如安全、事务管理、日志等。
此外,如果您将 AspectJ 与 AspectJ-maven-plugin 结合使用,那么您就能够在 CI 环境中针对您的方面运行单元测试,并且相信构建的构件已经得到了测试和正确编织。虽然您当然可以编写 Spring 驱动的单元测试,但是如果 LTW 失败,您仍然不能保证部署的代码将是测试过的代码。
以这种方式创建的代理将从一个切入点表达式开始应用,该切入点表达式测试框架,以确定将创建哪些 bean 和方法作为代理。这个建议的责任比您的代码更大。请记住,在这个过程中,切入点只捕获未声明为 final 的公共方法。
现在,在 Spring AOP 中,方面的编织将在容器启动时由容器执行,而在 AspectJ 中,您必须通过字节码修改对代码进行后期编译。出于这个原因,我认为 Spring 方法比 AspectJ 更简单、更易于管理。
另一方面,对于 Spring AOP,您不能使用 AOP 的所有能力,因为实现是通过代理完成的,而不是通过修改代码完成的。
与 AspectJ 一样,您可以在 SpringAOP 中使用加载时编织。您可以在春季通过代理和特殊配置(@EnabledLoadWeaving或 XML)实现此特性。您可以使用名称空间作为示例。然而,在 Spring AOP 中您不能拦截所有的情况。例如,SpringAOP 不支持 new命令。
@EnabledLoadWeaving
new
另一个需要考虑的问题是,你是否在一个能够直接监控服务器/应用程序启动成功或失败的环境中托管应用程序,或者你的应用程序是否部署在一个不在你监管之下的环境中(例如,它是由客户端托管的)。同样,这也为编译时间编织指明了方向。
但是在 Spring AOP 中,通过在 Spring 配置 bean 中使用 aspectof工厂方法,您可以从 AspectJ 的使用中获益。
aspectof
五年前,我更倾向于使用 Spring 配置 AOP,原因很简单,因为它更容易使用,而且不太可能损坏我的 IDE。然而,随着计算能力和可用内存的增加,这个问题已经变得不那么严重了,基于上面列出的原因,使用 Aspectj-maven-plugin 的 CTW 已经成为我工作环境中更好的选择。