Understanding AspectJ style with Spring AOP [duplicate] - java

This question already has answers here:
Spring AOP - why do i need aspectjweaver?
(5 answers)
Closed 7 years ago.
I'm reading spring documentation about AOP and now I'm at the section about using #AspectJ style.
Spring AOP is implemented in pure Java. There is no need for a special
compilation process. Spring AOP does not need to control the class
loader hierarchy, and is thus suitable for use in a Servlet container
or application server.
But in the section about #AspectJ style said
The #AspectJ support can be enabled with XML or Java style
configuration. In either case you will also need to ensure that
AspectJ’s aspectjweaver.jar library is on the classpath of your
application (version 1.6.8 or later).
As far as I know, aspectjweaver.jar performs the actual weaving of aspects at compile-time or load time. But Spring has its own proxy-based implementation. So I really don't see any reason for aspectjweaver.jar dependency.
That's true, to use #Aspect annotation we need aspectjrt dependency. But the dependency on weaver is not clear to me. Couldn't you explain in a nutshell how it actually works?

Spring AOP doesn't use the AspectJ weaver itself, but it reuses some of the classes from the aspectjweaver.jar file. It is used to define AspectJ-style pointcut expression, e.g. #Before.

Related

Compile/load time weaving with spring

The docs explain that, the LTW has to enabled either through the use of <context:load-time-weaver/> xml instruction or the use of #EnableLoadTimeWeaving annotation. However, I have done neither, but I still see that aspects are woven correctly in my projects!
In this case, I don't think they are woven at compile-time (but are they?), so it's surely got to be load-time-weaving?
Even if that's the case, how does it automatically choose to weave aspects in during load-time? Shouldn't the aspects remain unwoven if they are not turned on using one of the ways mentioned above as the docs say?
I've got the aspectj-weaver in my classpath, but that can't be enough to choose either of these weaving types anyway, can it?
Spring AOP does not rely on AspectJ byte code weaving. It just borrows the annotations used to define aspects from the AspectJ project. It is a separately implemented framework that uses run-time proxies to implement aspects. If you have <aop:aspectj-autoproxy /> in your application context then spring is using proxies to implement supported aspects defined on beans that are in the container.
Proxies can only achieve a sub-set of the full capabilities of the actual AspectJ system, basically advice that wraps methods. Due to their nature proxies have following limitations:
interception on external calls only (while breaching proxy boundary)
interception on public members only (private/protected can't be intercepted)
unawareness to local calls (or calls with this or super)
If you want to be able to advise fields for example, you would need to enable the use of Native AspectJ.

Spring Source Tool Help Needed

i am applying AspectJ in spring source tool
do i need to configure load time or compile weaving in spring source tool
i will be very happy if any provide details of using AspectJ for applying Aspect on Spring Source Tool
This is a very advanced topic, way beyond the scope of a single StackOverflow question.
Basically:
The simplest case is Spring AOP,
where you don't use AspectJ at all,
but create Java proxies from AspectJ
annotations. This is also the least
powerful option. Only a few pointcuts
are supported, and the targets must
be Spring Beans.
The most powerful option is static
AspectJ compilation, which you
usually integrate in your build
system (works fine with ant or
maven). Your class files are actually
changed to include the aspects. This
is called compile-time weaving.
Load-time weaving is somewhere
inbetween. You want to advise code,
but you don't want to change the
class files, so you "advise the
classloader" (this is not an adequate
definition, but it gives you an
idea). Loadtime-weaving is also
usually your only choice if you want
to add aspects to 3rd party library
code.
You should read AspectJ in Action by Ramnivas Laddad to understand all the subtle differences.
Either way, the settings you use in STS should reflect the settings you have in your build system. The section 7. Aspect Oriented Programming with Spring from the Spring Reference is also very helpful.

<tx:annotation-driven /> leads to java.lang.ClassNotFoundException: org.aopalliance.aop.Advice

Anybody has an idea why adding the annotation-driven declaration leads to the aopalliance classes not found. I have not explicitly defined the weaving so using Spring defaults.
Any help is appreciated
Spring has two modes of creating proxies to support transactions. The default mode is to create JDK proxies, but that only works if you inject interfaces. If you inject classes, CGLib proxies will be used, and they are created using AspectJ (and hence the aopalliance.jar and the spring-aspects.jar are needed on the classpath).
My advice: refer to your services and daos by interface:
private MyDaoInterface dao;
public void setDao(MyDaoInterface dao){
}
and Spring will automatically choose the Proxy-based approach.
See:
<tx:annotation-driven>
settings
Proxying mechanisms
I'm unsure what the real question is (if it is about the real cause1, providing the full stacktrace might be helpful) but the fact is that you are currently missing the aopalliance.jar on your classpath (which was previously included in Spring jars as mentioned in this thread or this blog post).
1 With the provided level of details, my guess is that Spring is loading its TransactionInterceptor which is an implementation of o.a.a.Advice and is looking for the dependency, which is missing.

Can Spring understand #Inject replacing Weld as a JSR-299 implementation?

I have noticed from several web pages that apparently Spring 3.0 supports #Inject from JSR-330. As we would really like to use JSR-299 syntax for dependency injection in our libraries for both web apps and stand-alone applications, and have alternatives to Weld, it would be nice if Spring could do this.
Being a novice to Spring, I tried downloading the Spring Framework distribution and put all jars on the Eclipse build path. No Inject annotation so my existing test project using Weld did not compile.
Can this be done with Spring? What do I need to do to get it running?
(I am aware that Guice eventually will support this too. It is only in SVN for now, and if there is an official Spring release which can, that would be better.)
It can be done. The JSR-330 jar must be downloaded seperately, and cglib to parse the manually written #Configuration classes, plus a commons logging implementation.
The largest difference from Weld seems to be that the wiring needs to be manually written instead of magically found (a bit more cumbersome, but may make more robust applications), plus the startup time is much less. I am still new to Spring - is there a way to have #Configuration classes autodiscovered?
From the Spring 3.0.x Reference documentation:
JSR 330's #Inject annotation can be used in place of Spring's #Autowired in the examples below. #Inject does not have a required property unlike Spring's #Autowire annotation which has a required property to indicate if the value being injected is optional. This behavior is enabled automatically if you have the JSR 330 JAR on the classpath.
So you can make your code agnostic of the DI framework by using #Inject, but you still need to include a jar with the javax.inject classes in your project because Spring does not ship them itself. You can find the relevant jar in the downloads section at JSR-330's Google Code site.
The javax.inject package is not included as part of Spring 3, but it does support it if it's present.
If you look at the source for AutowiredAnnotationBeanPostProcessor, you'll see the constructor uses reflection to locate javax.inject.Inject, and logs a message if it finds it. There's no compile-time dependency on it.
You'll need to locate the JSR-330 JARs from some other source (e.g. the JavaEE 6 SDK).

AspectJ load-time weaving configuration without XML

Is it possible to configure AspectJ LTW solely in Java? I don't want to deal with XML, and I was wondering if I can do without it. I searched through AspectJ website, and I found only the XML way.
I am planning to use it with Spring, hopefully without any strange consequences(had enough problems already:)).
Thanks!
You can set up Spring to use AspectJ via LTW mostly using Spring annotations. But you do need META-INF/aop.xml because this is an AspectJ LTW requirement, it does not come from Spring. AspectJ is an independent technology which does not need Spring, Spring only supports it being used in its own context.
If you don't like XML for whatever reason - done right there is no problem and you only need to touch the file once - use CTW (compile-time weaving), e.g. via AspectJ Maven Plugin.

Categories

Resources