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.
Related
I am having difficulties to differentiate between all these annotations tools and their use cases.
My guess, although the literature is confusing, is:
Custom Annotations are meant to be used in runtime retention policy as markers to be interpreted by means of Reflection API
Annotation Processing is meant to be used in class (for static checking at compile time) and source (for source generation) retention policies
AOP is meant to modify the code at runtime
So, do Custom Annotations and AOP make sense out of Runtime Retention Policy? Do Annotation Processing make sense out of Class/Source Retention Policies? Is the difference between AOP and Custom Annotations the sole fact that the laters are passive (you need to receive the annotated object as a param in order to do something)? Why is a framework like Checker needed at all?
Annotations are just a Java syntactic means to add information to classes, methods, fields or method parameters. There are three retention types specifying where the annotations are available:
SOURCE means that the annotations are only in the source code and being discarded during compilation.
CLASS means that the annotations are in the class file and available for bytecode processing steps after compilation. This is the default value.
RUNTIME means that you can read the annotations during runtime via reflection.
Annotation processing enables you to read annotations from your source code (i.e. even those with SOURCE retention) and use that information in order to generate more source code which can later be compiled. It is a kind of pre-processing step helping you to create boiler-plate code automatically instead of typing it manually.
AOP (Aspect-Oriented Programming) is an unrelated concept, please read Wikipedia or so in order to learn more. It is not meant to modify your code but its behaviour by weaving cross-cutting concerns into your main application logic. There are several ways to implement and apply AOP, e.g.
during runtime via dynamic proxies and delegation as Spring AOP does it or
via compile-time, binary or load-time weaving, all three of which are supported by AspectJ.
Incidentally, AOP tools like Spring AOP or AspectJ can access RUNTIME annotations. It does not mean you need to use annotations in order to apply aspects to your code, they are just one of several ways to mark and identify joinpoints in your application logic where aspects should be applied.
Besides, the AspectJ compiler also supports an annotation processing step, i.e. you can for example write an annotation processor creating new aspects or application classes from your source code annotations before compilation.
In order to explain all of this in more detail I would need to write a series of articles or a book, so please take it from here by yourself and learn about these concepts by reading other websites or books.
My question would be: how do I add a servlet filter, or a Spring AOP method (or a third solution - you name it) that cannot be removed from a web application without recompiling?
I'd like to solve license handling that way, but if anyone modifies the web.xml or the Spring config, the protection is gone.
Licence handling is definitely a cross-cutting concern which could (and IMO should) be modelled by means of AOP.
I cannot say much about servlet filters, being unexperienced in this regard, but
I know that Spring AOP is proxy-based, i.e. it does not modify the source code directly, which is not what you want.
AspectJ, on the other hand, when used at compile-time (not via load-time weaving as is the usual approach in Spring), does compile aspect code right into your core class files, "baking" them into your byte code. This is probably what you want. I do not say it cannot be reverse-engineered - there always is this option - but the code would not run without the AspectJ runtime on the classpath and you could not remove the licencing aspects without recompilation. So this is the option I recomment for that purpose.
Interesting question, by the way.
I came cross a article about AOP, there it is mentioned that Aspect weaving can happen during the compile time, class loading time and during runtime.
In java, I could imagine, rather understand, how aspect weaving would actually happens during compile time. Proxy class are generated during class compilation itself(with aspect enabled on project). Generated bytecode would have proxy code.
But I am still wondering what exactly (actually) happen, during class loading time weaving and runtime weaving. Does the proxy class gets generated while loading the class? Does aspect library add any programmatic instruction in .class (while compiling) file for proxy class generation?
Spring AOP actually uses Java Dynamic Proxies for interfaces and, if necessary, cglib for non-interface types. It only works for Spring Beans. Proxies are generated automatically for all methods matched by a so-called pointcut. This is done during wiring.
AspectJ however does not need or even use proxies, it directly generates byte code which is woven into the existing byte code. AspectJ is much more powerful and can do more than just method interception.
For compile-time weaving (CTW) this is done by the AspectJ compiler ajc. Instead of native AspectJ syntax (which is a superset of Java) you can also use a Java annotation style way of defining aspects, often called the #AspectJ syntax. In this case you can compile the aspects with javac and use the aspect weaver in a separate build step. The result is basically the same. In both cases, during runtime you need a small AspectJ runtime library in order for the aspects to work as expected.
The difference between CTW and LTW (load-time weaving) is that the weaving step is deferred until classloading time. In order to make this work you need a Java agent library, called the AspectJ weaver, on the JVM command line. Java agents are started before normal application classes are loaded and can thus influence classloading and instrument the loaded byte code as desired. This approach is also used by profiling tools or similar.
So obviously LTW does not work with source code but class files, i.e. AspectJ can weave its aspect code into any regular Java class file. This can also be done before runtime, i.e. you can weave aspect code into an external library for which you do not have the source code, creating a new, modified version of it in order to save the time for LTW every time the library is loaded. This often is called binary weaving. With some extra knowledge it is even possible to weave aspect code into the JDK, i.e. by creating a modified rt.jar including aspect code. But this is nothing you normally do, I just wanted to mention that it is possible.
Not necessarily at compile time. In Java, through reflection and classloader, you can see and even or modify create methods and classes at runtime, programmatically.
For example,
"hello".getClass().getMethod("substring", Integer.TYPE).invoke("my sharona", 3)
Will return "sharona", extracting the method substring from a String instance and applying it to another object.
Using a custom classloader, you can define how your class is loaded from the system. This way you can define a method which will called to load (or generate!) the bytecode for a class. You can also use the system classloader to load the bytecode of a class and inspect it.
This technique is widely used by Mozilla Rhino, which can use it to load a compiled JavaScript as a Java bytecode for greater efficiency, or JavAssist, which allows you to create classes, methods, fields and anything at runtime.
Also application servers like JBoss or TomCat use reflection to inspect and manipulate the code, especially through annotations.
Not sure what run-time weaving is. In load-time weaving the agent intercepts the class loading and modifies the byte-code before passing it on to the class loader.
To see how this works is quite easy, for example using AspectJ. You could use compile time weaving and disassemble the code to see exactly how it works. AspectJ can also be instructed to save on disk the generated classes during load time weaving.
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.
i want to intercept method from a non-proxied object.
I have a class instance MyClass myClassInstance=new MyClass() and i want to intercept call of myClassInstance methods.
I know all works good with proxies, but i need aspect on non proxied.
Is this possible?
Thanks.
It is possible, but it is not desirable.
You can use #Configurable and AspectJ will intercept calls. Read the 7.8.1 Using AspectJ to dependency inject domain objects with Spring section of the docs about it.
In short - AspectJ plugs some "magic" either compile-time or load-time (with a respective weaver), which modifies the classes so that they become part of the spring context.
As of why I think it is undesirable - this is dark magic that happens by modifying the classes' structure. It's not an object-oriented approach, and I think it will be hard to support. Imagine 6 months later a colleague of yours is debugging a nasty issue. It could take days before he realizes this magic is happening. This opinion is subjection though. The functionality is there and if you need it - use it.
Using Spring, I do not believe so (I appear to be wrong), using AspectJ I believe you can as long as you compile all the code with the AspectJ compiler. However I have never tried it.
You can enable load time weaving in Spring. Then the class loader will weave whatever aspects you define into your classes when they are loaded - regardless of whether they are being created by Spring.
You'll need to enable LTW by adding this line to your context file:
See:
http://static.springsource.org/spring/docs/3.0.0.M4/spring-framework-reference/html/ch07s08.html#aop-aj-ltw