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, Asp开发者_如何学运维ectJ 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?
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
- This is proxy-based AOP, so basically you can only use method-execution joinpoints.
- Aspects aren't applied when calling another method within the same class.
- There can be a little runtime overhead.
- Spring-AOP cannot add an aspect to anything that is not created by the Spring factory
AspectJ Pros
- This supports all joinpoints. This means you can do anything.
- There is less runtime overhead than that of Spring AOP.
AspectJ Cons
- Be careful. Check if your aspects are weaved to only what you wanted to be weaved.
- You need extra build process with AspectJ Compiler or have to setup LTW (load-time weaving)
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.
Apart from what others have stated - just to rephrase, there are two major differences
:
- One is related to the type of weaving.
- Another to the joinpoint definition.
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 the aspectj
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.
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 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 AOP is one of the most important parts of the framework.
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, the new
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
This article also has a good explanation regarding the topic.
Spring AOP and AspectJ have different goals.
Spring AOP aims to provide a simple AOP implementation across Spring IoC to solve the most common problems that programmers face.
On the other hand, AspectJ is the original AOP technology which aims to provide complete AOP solution.
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.
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.
精彩评论