Spring AOP 与 AspectJ
我的印象是 Spring AOP 最适合用于特定于应用程序的任务,例如安全性、日志记录、事务等,因为它使用自定义 Java5 注释作为框架。然而,AspectJ 的设计模式似乎更加友好。
谁能强调一下在 Spring 应用程序中使用 Spring AOP 与 AspectJ 的各种优缺点?
I am under the impression that Spring AOP is best used for application specific tasks such as security, logging, transactions, etc. as it uses custom Java5 annotations as a framework. However, AspectJ seems to be more friendly design-patterns wise.
Can anyone highlight the various pros and cons of using Spring AOP vs AspectJ in a Spring application?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
与AOP相比,AspectJ不需要在编译时增强目标类。相反,它在运行时为目标类生成一个代理类,该代理类要么实现与目标类相同的接口,要么是目标类的子类。
总之,代理类的实例可以用作目标类的实例。一般来说,编译时增强的AOP框架在性能上更有优势——因为运行时增强的AOP框架每次运行时都需要动态增强。
Compared to AOP, AspectJ does not need to enhance the target class at compile time. Instead, it generates a proxy class for the target class at runtime, which either implements the same interface as the target class or is a subclass of the target class.
In summary, an instance of a proxy class can be used as an instance of a target class. In general, the compile-time enhanced AOP framework is more advantageous in performance—because the runtime-enhanced AOP framework requires dynamic enhancements every time it runs.
这篇文章也对这个主题有很好的解释。
This article also has a good explanation regarding the topic.
重要的是要考虑您的方面是否是关键任务以及您的代码部署在哪里。 Spring AOP 将意味着您依赖于加载时编织。这可能无法编织,根据我的经验,这意味着可能存在记录的错误,但不会阻止应用程序在没有方面代码的情况下运行[我会添加一个警告,即可以通过以下方式配置它:事实并非如此;但我个人并不知道]。编译时编织避免了这种情况。
此外,如果您将 AspectJ 与aspectj-maven-plugin 结合使用,那么您可以在 CI 环境中针对方面运行单元测试,并确信构建的工件经过测试并正确编织。虽然您当然可以编写 Spring 驱动的单元测试,但您仍然无法保证部署的代码将是在 LTW 失败时经过测试的代码。
另一个考虑因素是您是否将应用程序托管在能够直接监视服务器/应用程序启动成功或失败的环境中,或者您的应用程序是否部署在不受您监督的环境中[例如,由客户托管]。同样,这将为编译时间编织指明方向。
五年前,我更支持 Spring 配置的 AOP,原因很简单,它更容易使用,并且不太可能占用我的 IDE。然而,随着计算能力和可用内存的增加,这已经不再是一个问题,并且基于我上面概述的原因,带有aspectj-maven-plugin的CTW已经成为我的工作环境中更好的选择。
It is important to consider whether your aspects will be mission critical and where your code is being deployed. Spring AOP will mean that you are relying on load-time weaving. This can fail to weave and in my experience has meant that logged errors may exist but will not prevent the application from running without aspect code [I would add the caveat that it may be possible to configure it in such a way that this is not the case; but I am not personally aware of it]. Compile-time weaving avoids this.
Additionally, If you use AspectJ in conjunction with the aspectj-maven-plugin then you are able to run unit tests against your aspects in a CI environment and have confidence that built artifacts are tested and correctly woven. While you can certainly write Spring driven unit tests, you still have no guarantee that the deployed code will be that which was tested if LTW fails.
Another consideration is whether you are hosting the application in an environment where you are able to directly monitor the success or failure of a server / application startup or whether your application is being deployed in an environment where it is not under your supervision [e.g. where it is hosted by a client]. Again, this would point the way to compile time weaving.
Five years ago, I was much more in favour of Spring configured AOP for the simple reason that it was easier to work with and less likely to chew up my IDE. However, as computing power and available memory have increased this has become much less of an issue and CTW with the aspectj-maven-plugin has become a better choice in my work environment based on the reasons I have outlined above.
spring 用户手册会提供很多信息,直接从马嘴里说出来。
6.4 章 - 选择使用哪种 AOP 声明样式 非常适合您,因为它讨论了两者的优缺点。
段落 6.1.2 - Spring AOP 的能力和目标 &章节 6.2 - @Aspect 支持 和6.8 - 在 Spring 应用程序中使用 AspectJ 应该特别有趣。
The spring user manual will give a lot of information, straight from the horse's mouth.
The chapter 6.4 - Choosing which AOP declaration style to use is dead on for you since it discusses the pros and cons of both.
The paragraph 6.1.2 - Spring AOP Capabilites and goals & chapters 6.2 - @Aspect support and 6.8 - Using AspectJ with Spring applications should be particularily interesting.
Spring AOP是Spring框架的重要组成部分之一。在非常基础的阶段,spring框架是基于IoC和AOP的。 Spring的官方课程中有一张幻灯片,上面写着:
理解 Spring 中的 AOP 如何工作的关键点是,当您使用 Spring 编写 Aspect 时,我们会通过为您的对象构建代理来检测框架,如果您的 bean 实现了接口或通过 CGLIB,则使用
JDKDynamicProxy
如果您的 bean 没有实现任何接口。请记住,如果您使用 Spring 3.2 之前的版本,则您的类路径中必须有 cglib 2.2。从 Spring 3.2 开始,它就没用了,因为 cglib 2.2 已包含在核心中。创建 bean 时的框架将创建一个代理来包装您的对象并添加横切关注点职责,例如安全性、事务管理、日志记录等。
以这种方式创建的代理将从切入点表达式开始应用,该表达式使框架决定将创建哪些 bean 和方法作为代理。该建议将比您的代码承担更多责任。请记住,在此过程中,切入点仅捕获未声明为最终的公共方法。
现在,在 Spring AOP 中,方面的编织将由容器在容器启动时执行,而在 AspectJ 中,您必须通过字节码修改对代码进行后编译来执行此操作。因此,我认为 Spring 方法比 AspectJ 更简单、更易于管理。
另一方面,使用 Spring AOP,您无法使用 AOP 的所有功能,因为实现是通过代理完成的,而不是通过修改代码来完成的。
与在 AspectJ 中一样,您可以在 SpringAOP 中使用加载时编织。您可以从 Spring 中通过代理和特殊配置、
@EnabledLoadWeaving
或 XML 实现的此功能中受益。您可以使用名称空间作为示例。然而在 Spring AOP 中你不能拦截所有的情况。例如,Spring AOP 不支持new
命令。然而,在 Spring AOP 中,您可以通过在 spring 配置 bean 中使用
aspectof
工厂方法来受益于 AspectJ 的使用。由于Spring AOP基本上是从容器创建的代理,因此您只能将AOP用于Spring bean。而使用 AspectJ,您可以在所有 bean 中使用方面。另一个比较点是调试和代码行为的可预测性。使用 Spring AOP,该工作全部由 Java 编译器执行,方面是为 Spring bean 创建代理的一种非常酷的方式。在 AspectJ 中,如果修改代码,则需要更多编译,并且理解方面的编织位置可能会很困难。即使在 Spring 中关闭编织也更简单:使用 Spring,您可以从配置中删除该方面,重新启动,它就可以工作了。在AspectJ中你必须重新编译代码!
在加载时编织中,AspectJ 比 Spring 更灵活,因为 Spring 并不支持 AspectJ 的所有选项。但在我看来,如果您想更改 bean 的创建过程,更好的方法是在工厂中管理自定义登录,而不是通过加载时编织改变新操作员行为的方面。
希望这篇AspectJ和Spring AOP的全景可以帮助你理解这两种药水的区别
Spring AOP is one of the essential parts of the spring framework. At the very basic stage, the spring framework is based on IoC and AOP. In the official course of Spring there is a slide in which it says:
The key point for understanding how AOP in Spring works is that when you write an Aspect with Spring we instrument the framework with building a proxy for your objects, with a
JDKDynamicProxy
if your bean implements an interface or via CGLIB if your bean doesn't implement any interface. Remember that you must have cglib 2.2 in your class-path if you're using Spring prior to version 3.2. Starting from Spring 3.2 it is useless because cglib 2.2 was included in the core.The framework at the bean creation will create a proxy that wraps your objects and adds cross cutting concerns responsibilities such as security, transaction management, logging and so on.
The proxy creation in this way will be applied starting for a pointcut expression that instruments the framework to decide what beans and methods will be created as proxies. The advice will be the more responsibility than for your code. Remember that in this process the pointcut captures only public methods that aren't declared as final.
Now, while in Spring AOP the weaving of Aspects will be performed by the container at container start-up, in AspectJ you have to perform this with a post compilation of your code through bytecode modification. For this reason in my opinion the Spring approach is simpler and more manageable than AspectJ.
On the other hand, with the Spring AOP you can't use the all power of AOP because the implementation is done through proxies and not with through modification of your code.
As in AspectJ, you can use load-time weaving in SpringAOP. You can benefit from this feature in spring is implemented with an agent and special configurations,
@EnabledLoadWeaving
or in XML. You can use the name-space as an example. However in Spring AOP you can't intercept all the cases. For example, thenew
command isn't supported in Spring AOP.However in Spring AOP you can benefit from the usage of AspectJ through the use of the
aspectof
factory method in the spring configuration bean.For the reason that Spring AOP is basically a proxy created from the container, so you can use AOP only for spring beans. While with AspectJ you can use the aspect in all your beans. Another point of comparison is debug and the predictability of the code behavior. With spring AOP, the job is preformed all from the Java compiler and aspects are a very cool way for creating proxy for your Spring bean. In AspectJ if you modify the code, you need more compiling and to understand where your aspects are woven could be hard. Even shutting down the weaving in spring is simpler: with spring you remove the aspect from your configuration, restart and it works. In AspectJ you must recompile the code!
In load-time weaving, AspectJ is more flexible than Spring because Spring doesn't support all of the options of AspectJ. But in my opinion If you want to change the creation process of a bean, a better way is to manage the custom login in a factory and not with load-time weaving of an aspect that changes the behavior of your new operator.
I hope that this panoramic of AspectJ and Spring AOP helps you understand the difference of the two potions
附加说明:如果高负载下的性能很重要,您将需要比 Spring AOP 快 9-35 倍的 AspectJ。 10ns 与 355ns 可能听起来并不算多,但我见过人们使用很多方面。 10K 的方面价值。在这些情况下,您的请求可能涉及数千个方面。在这种情况下,您需要将 ms 添加到该请求中。
请参阅基准。
An additional note: If performance under high load is important, you'll want AspectJ which is 9-35x faster than Spring AOP. 10ns vs 355ns might not sound like much, but I've seen people using LOTS of Aspects. 10K's worth of aspects. In these cases, your request might hit a thousands of aspects. In that case you're adding ms to that request.
See the benchmarks.
除了其他人所说的之外 - 只是换句话来说,
有两个主要区别
:Spring-AOP:通过代理进行运行时编织,如果接口存在,则使用动态代理的概念;如果提供直接实现,则使用 cglib 库。
AspectJ:编译时编织如果源可用或编译后编织(使用编译文件),则通过
AspectJ Java Tools(ajc编译器)
。此外,还可以启用 Spring 的加载时编织 - 它需要aspectj
定义文件并提供灵活性。编译时编织可以提供性能优势(在某些情况下),而且 Spring-aop 中的连接点定义仅限于方法定义,而 AspectJ 则不然。
Apart from what others have stated - just to rephrase,
there are two major differences
:Spring-AOP: Runtime weaving through proxy using concept of
dynamic proxy if interface exists or cglib library if direct implementation provided.
AspectJ: Compile time weaving through
AspectJ Java Tools(ajc compiler)
if source available or post compilation weaving (using compiled files). Also, load time weaving with Spring can be enabled - it needs theaspectj
definition file and offers flexibility.Compile time weaving can offer benefits of performance (in some cases) and also the
joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.
Spring-AOP 优点
它比 AspectJ 使用起来更简单,因为您不必使用 LTW (加载时编织)或 AspectJ 编译器。
它使用代理模式和装饰器
模式
Spring-AOP
AspectJ 优点
AspectJ 缺点
Spring-AOP Pros
It is simpler to use than AspectJ, since you don't have to use LTW (load-time weaving) or the AspectJ compiler.
It uses the Proxy pattern and the Decorator
pattern
Spring-AOP Cons
AspectJ Pros
AspectJ Cons