I am studying for Spring Core certification and I have a doubt related how Spring handle AOP.
Reading the documentation it seems to understand that exist 2 way to obtain AOP in Java:
Using AspectJ that using byte code modification for aspect weaving offers a full-blown Aspect Oriented Programming language. (so it seems to me that AspectJ is a differnt language that can be integrated with Java to offer it the AOP features).
Spring AOP: used in Spring framework that uses dynamic proxies for aspect weaving instead the bytecode modification.
So my doubts are mainly the followings:
1) Reading the documentations found the following method to add the AOP support to my Spring application:
USING JAVA CONFIGURATION CLASS:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan(basePackages=“com.example”)
public class AspectConfig {
...
}
USING XML CONFIGURATION:
<beans>
<aop:aspectj-autoproxy />
<context:component-scan base-package=“com.example” />
</beans>
As you can see in both configurations there is a reference to AspectJ:
#EnableAspectJAutoProxy
and
<aop:aspectj-autoproxy />
Why? If Spring use Spring AOP instead AspectJ why there is a reference to AspectJ when I configure AOP in Spring?
2) In the previous examples are show 2 way to configure Spring: by Java configuration class and by XML configuration. I know that exist a third way to configure a Spring application: by the use of annotations. So exist a way to configure AOP using the annotations?
I think that these Spring AOP settings with references to AspectJ in their names are indeed more irritating than helpful. I can understand why you are confused. Spring AOP is really a different concept from AspectJ. As you said: dynamic JDK or CGLIB proxies in Spring AOP versus byte code instrumentation during compile or load time in AspectJ. Other differences are:
AspectJ compile-time weaving needs a special compiler called Ajc. It is basically an Eclipse Java compiler Ecj enhanced by the aspect weaver which does the instrumentation. In contrast, Spring AOP creates dynamic proxies during runtime.
In AspectJ there are two syntax variants: native and annotation-based. The former is more elegant and expressive, a superset of Java and definitely needs Ajc to be compiled. The latter uses Java annotations and can be compiled with Javac, but needs the aspect weaver contained both in Ajc (compile time) and in the weaving agent aspectjweaver.jar (load time) to "finish" them and make them usable during runtime. Both variants need the AspectJ runtime contained in both aspectjrt.jar (very small, used for compile-time-woven aspects during runtime) and aspectjweaver.jar (much bigger, used for load-time weaving, contains both the runtime and the weaver).
AspectJ works for any Java class, it does not need or even know about the Spring framework. Spring AOP needs the Spring framework as a foundation, you can only instrument Spring Beans/Components with it, not Spring-agnostic POJOs.
AspectJ is more efficient because it avoids proxies. But Spring AOP is an optional part of the Spring framework anyway, so if you use Spring and method execution interception of Spring Beans is all you need, it makes perfect sense to use it.
Spring AOP uses a subset of the AspectJ pointcut syntax. Maybe this is the subtle reason why Spring AOP uses AspectJ references, but I still think it was a bad decision to not differentiate the two concepts from one another more clearly with regard to nomenclature. Besides, the common poinctut language subset is defined in a little JAR called aopalliance.jar because long ago a so-called "AOP Alliance" has defined that syntax. The dominating and by far most powerful AOP language today is AspectJ, though, so in reality AspectJ (maintained by Eclipse) is the leader in that area, IMO.
When I say that Spring AOP uses a subset of AspectJ syntax, conversely it means that AspectJ offers a superset. There are more pointcut types such as call(), set(), get() etc. and you have way more options to intercept joinpoints and apply cross-cutting concerns to your code base via advice or inter-type definition.
I do not understand your question #2. The configuration class in your example does use annotations, so there is no third way. ;-) But there is an old, really outdated AOP approach in Spring called interceptors. It is a leftover of an early AOP approach and kind of obsolete nowadays, even though it is still usable.
Both Spring AOP and AspectJ can be configured via XML or annotations within Spring. :-)
Not sure if I completely understand your question, I think you are asking something like: "If I'm using Spring AOP, why do I see references to AspectJ?"
If that's the case, you should know that Spring is not in competition with AspectJ, but rather leverages AspectJ for AOP.
See Spring documentation: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html
Related
I'm trying to understand what Spring AOP is and how it works. The questions I can't answer are the following:
One of the reasons why Spring AOP is not used compared to AspectJ is that Spring AOP cannot add an aspect to anything that is not created by the Spring factory. What does this mean? Isn't everything created from the Spring Factory?
How does Spring Core use the Spring AOP module "behind the scenes"?
What is meant by "Spring AOP is proxy-based"?
One of the reasons why Spring AOP is not used compared to AspectJ is
that Spring AOP cannot add an aspect to anything that is not created
by the Spring factory. What does this mean? Isn't everything created
from the Spring Factory?
In short, that Spring builds proxies for the beans in the Container, and relyies on these proxies to implement AOP.
Regarding the comparison with AspectJ:
From the Spring.io reference docs:
"
...
Thus, for example, the Spring Framework’s AOP functionality is normally used in conjunction with the Spring IoC container. Aspects are configured by using normal bean definition syntax (although this allows powerful “auto-proxying” capabilities). This is a crucial difference from other AOP implementations. You cannot do some things easily or efficiently with Spring AOP, such as advise very fine-grained objects (typically, domain objects). AspectJ is the best choice in such cases. However, our experience is that Spring AOP provides an excellent solution to most problems in enterprise Java applications that are amenable to AOP.
Spring AOP never strives to compete with AspectJ to provide a comprehensive AOP solution. We believe that both proxy-based frameworks such as Spring AOP and full-blown frameworks such as AspectJ are valuable and that they are complementary, rather than in competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance API. Spring AOP remains backward-compatible. See the following chapter for a discussion of the Spring AOP APIs."
What is meant by "Spring AOP is proxy-based"?
How does Spring Core use the Spring AOP module "behind the scenes"?
Proxy based means that, beans are wrapped in another object (the proxy) which itercepts the calls to the obejct and can act upon that interception before calling the real method on the wrapped oject.
There are two ways of implementing this, one is using java Dynamic Proxys (Reflection), the other is using CGLIB, a library that adds the proxy capability at bytecode level.
Spring.io reference docs AOP
An article about Proxys
You should read this for comparison https://stackoverflow.com/questions/1606559/spring-aop-vs-aspectj&ved=2ahUKEwim6cD24-DoAhVMzaQKHd4SDfMQFjAMegQICRAB&usg=AOvVaw1Sps_B0sPQPKRD5N9UtOpA&cshid=1586622128032
I looked at many Aspectj tutorials in web and most of them are:
Aspectj config with Spring beans. Per my understanding, if I am using
javaagent:./src/main/resources/aspectjweaver.jar
and
if I created aop.xml, aspectj weaving will work for all classes and objects (including those managed by Spring).
Why do I need to enable weaving in Spring? (like in this tutorial). What's the benefit of doing:
<!-- this switches on the load-time weaving -->
<context:load-time-weaver/>
AspectJ does not require Spring. You can use aspectJ in your applications and benefit from the AOP paradigm.
Spring makes things a bit easier providing instrumentation to perform load-time-weaving easily, detecting Sun's GlassFish, Oracle's OC4J, Spring's VM agent and any ClassLoader supported by Spring's ReflectiveLoadTimeWeaver.
For example, in case of Tomcat, Spring offers TomcatInstrumentableClassLoader which adds instrumentation to loaded classes without the need to use a VM-wide agent.
On the other hand, spring provides aspectJ integration which goes beyond the scope of your question. But basically allows you to handle non managed spring beans in many ways (dependency injection, transactions...).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Spring AOP vs AspectJ
I am reading spring reference document. In that it is written
If you need field access and update join points, consider a language such as AspectJ.
There are something that you can not do with Spring AOP, such as advise very fine grained objects (such as domain objects), AspectJ is the best case to work with it.
What is AspectJ compiler or weaver?
I did not get the meaning of above three points and hence confused. Please elaborate with simple example.
AFAIK Spring AOP doesn't support all functionalities of AspectJ, but only a limited set.
For example, Spring AOP supports only method-level pointcuts, so if you want fine grained control (i.e. field-level) you need to use AspectJ natively.
Your first point simply conveys that you can only apply point-cuts on method level, field interception is not implemented in spring-aop.
Next point tells that you cannot add advices on domain-objects(which are simple pojo entities),
The last is about weaving ,weaving is wiring of Aspects into objects in the spring XML file in the way as JavaBean. OR simply say, weaving is about adding new bytecode to your java class to make it usable to the framework.
also there is more important difference - AspectJ can inject AOP stuff at compile time(with aspectj maven pluging for example), spring AOP only at runtime using cglib or javasist according to the version of spring. However generally you would prefer spring AOP anyway - just because it much easier...
We can use both #AspectJ annotation style to define aspects, as well as the AspectJ Java extension language, which requires us to use the ajc compiler.
What are the reasons that one would want to use the annotation style instead of ajc? It seems to me that a lot of functionality is given up by using annotation style, but not much (if anything) is gained, other than not having to use ajc (what's so bad about having to use ajc?)
Could someone please enlighten me on this topic?
Both styles (.aj and #AspectJ) have features that the other cannot do.
See this post for something the annotations can do that declarative AspectJ cannot: What is the AspectJ declaritive syntax for overwritting an argument
The .aj files for the most part (other than mentioned above) can do way more.
Most notable they can do ITDs (Inter-Type-Definitions aka adding methods and properties to classes).
The biggest reason you would want to use the #AspectJ is that it does not even require compile time weaving (CTW) or even load time (LTW) if you use Spring proxy AOP support. Spring will mimic #AspectJ but at runtime by creating proxies.
I have noticed that Spring, Eclipse (and myself) seem to be encouraging greater use of true AspectJ. I believe this is because the Eclipse plugin has gotten so good. Also with true AspectJ and the #Configurable annotation you can get Spring wiring on instantiated beans. This is how Spring Roo works.
With the Eclipse AspectJ IDE plugin you can see the pointcut references to both styles (# and aj) and get a very clear idea of what "magic" is happening.
Adding some additional step to your build process is not the easiest and good way. Especially when you have large project. You go away from all java tools and IDE support, which may not supports *.aj syntax.
I've been using spring for some time, but I always wondered how does it work, more specifically, how do they load and weave beans/classes marked only with an interface or #annotation.
For the xml declarations, it's easy to see how spring preprocesses my beans (they are declared in the xml context that spring reads), but for the classes marked only with annotations, I can't see how that works, since I don't pass any agent to the jvm or so.
I believe there is some Java/JVM hook that allows you to preprocess classes by some sort of criteria, but I wasn't able to found out anything on the docs.
Can someone point me to some docs? Is this related to the java.lang.instrument.ClassFileTransformer API?
Actually by default Spring does not
do any bytecode postprocessing
neither for XML-, nor
annotation-configured beans. Instead
relevant beans are wrapped into dynamic
proxies (see e.g.
java.lang.reflect.Proxy in the
Java SDK). Dynamic proxies wrap the
actual objects you use and intercept
method calls, allowing to apply AOP
advices. The difference is that proxies are essentially new artificial classes created by the framework, whereas weaving/bytecode postprocessing changes the existing ones. The latter is impossible without using the Instrumentation API you mentioned.
As for the annotations, the implementation of <context:component-scan> tag will scan the classpath for all classes with the Spring annotations and create Spring metadata placeholders for them. After that they are treated as if they were configured via XML (or to be more specific both are treated the same).
Although Spring doesn't do bytecode postprocessing itself you can configure the AspectJ weaving agent that should work just fine with Spring, if proxies do not satisfy you.