NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies:
17 -
Pages:
2
[
12
| Next
]
Threads:
[
Previous
|
Next
]
One of the strengths of the Spring Framework is its robust and flexible aspect oriented programming infrastructure.
In Spring, AOP is a little different than other AOP frameworks in that it brings with it a
consistent AOP infrastructure that can be applied for other AOP technical solutions. Out of the
gate, Spring supports dynamic-proxy-based AOP, and CGLib-based AOP. Both of these have their
limitations, but can honestly be used in a very large majority of cases. Spring does have
integration support
with
AspectJ
as well, however, so don't worry.
Thankfully, the AspectJ integration is not drastically different from the regular AOP, which
I think shows some of the strengths of Spring's AOP infrastructure; even an AOP library as
different as AspectJ can still be integrated.
General Education
Spring's 'built-in' AOP infrastructure is defined by the
org.springframework.aop.*
packages.
To understand the packages, you have to have at least some idea of the concepts of AOP as Spring models
these concepts *very* closely in implementation, so I'll explain them. Now... every article I read on AOP
seems to just try to confuse me - and the vocabulary around AOP even makes it worse. I'm going to do my
best to describe things as simply as possible, so bear with me:
Aspect
- Think of this as the general feature you want to apply globally to your application (logging,
performance monitoring, exception handling, transaction management, etc).
Advice
- A chunk of code that is invoked during program execution, and is a piece of the logic for
implementing your aspect. This is the first important piece of a Spring AOP aspect implementation! I like
to compare advice implementations to the decorator pattern. While an advice doesn't necessarily wrap
an entire object in concept, it has the same general effect. We'll learn in a bit that how that advice is applied is
more granular/formal than typically defined in the decorator pattern however.
Joinpoint
- A *single* location in the code where an advice should be executed (such as field access,
method invocation , constructor invocation, etc.). Spring's built-in AOP only supports method invocation currently,
so joinpoints aren't particularly important to focus on at this point.
Pointcut
- A pointcut is a set of many joinpoints where an advice should be executed. So if, in Spring,
a joinpoint is always a method invocation, then a pointcut is just a set of methods that, when called, should have advices
invoked around them. This is the second important pieces of a Spring AOP aspect implementation!
Targets/Target Objects
- The objects you want to apply an aspect or set of aspects to!
Introduction
- This is the ability to add methods to an object. This is closely tied to, and is almost analogous
to the term 'mixins'. It's really just a way to make an object of type A also an object of type B. Introduction in
Spring is limited to interfaces.
Spring and Advice Objects
I like to start with the concept of advice objects, because they are the easiest to bridge to from a non-AOP
way of thinking, because an advice is really very similar to a decorator (as I mentioned above). Advice implementations
in Spring are simply implementations of the
org.aopalliance.intercept.MethodInterceptor
interface. Woah! Wait a minute -
that's not a Spring class! Nope - it turns out that Spring's AOP implementation uses a *standard* AOP API from the AOP Alliance, which
you can
read more about here
. The
MethodInterceptor
interface is actually a child of the
org.aopalliance.intercept.Interceptor
interface, which is a child of
another
interface,
org.aopalliance.aop.Advice
- Whew!. Remember that I said Spring AOP only supports method invocation, but
that conceptually, an advice could include field access, constructor invocation and a bunch of other things. That is why Spring's advice starts at the
MethodInterceptor
interface, even though there are other interfaces higher up - because MethodInterceptor is the sub-interface that is designed for method-invocation
style advice and for which Spring has support. The
MethodInterceptor
interface is really quite simple:
Basically, when you write an advice for intercepting a method, you have to implement one method - the
invoke
method, and you are given a
MethodInvocation
object to work with. The
MethodInvocation
object
tells us a bunch of stuff about the method that we're intercepting, and also gives a hook to tell the method to go ahead and
run.
Let's jump right in and look at a (very) basic method performance profiling advice:
import org.aopalliance.intercept.*;
publicclass PerformanceInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation method) throws Throwable {
long start = System.currentTimeMillis();
try {
Object result = method.proceed();
return result;
}
finally {
long end = System.currentTimeMillis();
long timeMs = end - start;
System.out.println("Method: " + method.toString() + " took: " + timeMs +"ms.");
}
}
}
Not too complicated really - just capture the time before the method invocation, tell the method to go ahead
and run, then afterward capture the time again, calculate the difference, and print it out. Incidentally,
Spring already has a better implementation of this type of interceptor - the
org.springframework.aop.interceptor.PerformanceMonitorInterceptor
-
there are actually quite a few useful concrete interceptor implementations in there - check it out.
Spring has multiple alternatives to the basic
MethodInterceptor
, however, (which is referred to in the
Spring documentation as an 'around' advice) so that if you want to do
more specific things, you can with less complication - these extensions come in the form of Spring-specific extensions to the
Advice
interface (siblings to the
MethodInterceptor
interface), and they include:
org.springframework.aop.MethodBeforeAdvice
- Implementations of this interface have to implement
this contract:
You'll notice in this case you aren't given the
MethodInvocation
object, just the underlying
Method
object - this is because the call to
proceed()
will be handled by Spring for you; all you need to do is
do what you need *before* the method is called (as the interface name implies).
org.springframework.aop.AfterReturningAdvice
- This is the pong to the ping of
MethodBeforeAdvice
.
This interface's method will be called on the return from the invocation of a method. The contract looks like this:
You'll notice it looks a whole like the before advice, but simply adds the Object's return value to the
method arguments.
org.springframework.aop.ThrowsAdvice
- This is a strange implementation. Instead of requiring you
to implement a particular contract, this is simply a 'marker' interface, and expects you to implement any number
of methods that look like this:
void afterThrowing([Method], [args], [target], [some type of throwable] subclass)
Oddly enough, the only mandatory argument is the
Throwable
sub-type.
Here is a snapshot that generally covers the 'advice' hierarchy:
That's a primer on advice objects. Not too bad so far, right? If you've ever worked with in reflection in Java,
most of this is fairly similar in style.
Spring and Pointcuts
What seperates AOP from object-oriented design patterns such as the decorator pattern, at least when talking about
Spring AOP, is the fact that the *what* is defined seperately from the *where* (or would it be *whom*?). In other words, the 'advice', which is the
code to be invoked, is disconnected entirely from the particular item it is 'advising' - which, again, in the
Spring case is always a method. In other words, an advice in Spring doesn't have any association, type binding, dependency,
or any other form of direct awareness of the method it is working with.
Remember that the thing that an advice works with is called a
JoinPoint
. Our join points in Spring
are always methods, and at runtime resolve to
org.aopalliance.aop.Method
objects which have made appearances
as method arguments to our advices above. To solidify the point,
org.aopalliance.aop.Method
extends
org.aopalliance.aop.JoinPoint
.
The reason I am bringing joinpoints back up is because a
Pointcut
object is all about defining all of the
joinpoints that an advice should be 'applied to'. In Spring terms, a pointcut defines all of the methods that our
interceptor should intercept. Pointcuts in Spring implement the
org.springframework.aop.Pointcut
interface
and look something like this:
The class filter is a special type of object that describes which classes have potential joinpoints (read methods)
on them. The method matcher simply describes which methods for a given class are considered valid joinpoints for this
pointcut. I don't want to spend too much time on the pointcut interface, however, because chances are - you won't be
implementing it.
Static vs. Dynamic Method Matching
Spring makes a distinction between static and dynamic method matching. A static method matching pointcut (a subclass of the
org.springframework.aop.support.StaticMethodMatcherPointcut
class) knows at the time it
proxies a target object what methods it considers joinpoints on that object. A dymamic method matching pointcut (see below for
implementation details), on the other
hand must be consulted at *every* method invocation. This is a useful implementation detail because a static method matcher,
while having less flexibility (you can't check the method invocation arguments), is, by design, much faster, as the check
is only performed once, rather than at every method invocation. Static Matching pointcuts implementations look something
like this:
In most cases, however, this is irrelevant, because there is a very convenient pair of static method matchers that
cover almost all concerns - the
org.springframework.aop.support.JdkRegexpMethodPointcut
and
org.springframework.aop.support.PerlRegexpMethodPointcut
classes. You typically configure these outside
of your code (we'll get to configuration in a bit), and don't have to do any nasty reflection checks as seen above.
In addition, there is a simpler variety of text-based matching called the
NameMatchedMethodPointcut
-
which is similar to the regex implementations, but only matches exact names.
Dynamic matching pointcut implementations typically look something like this:
Due to the nature of dynamic pointcuts, there are no real convenience implementations of this class. Here is what the
pointcut hierarchy generally looks like:
You may have noticed, neither of my pointcut examples made any reference to any advice (e.g.
MethodInterceptor
implementation) -
remember that I said an advice knows the *what*, not the *where*? Well, a pointcut is the inverse - it knows the *where*, not
the *what*. Therefore, theoretically, these two components can be intermingled in different configurations and reused.
Tying Pointcuts with Advisors - PointcutAdvisors
I've gone to great lengths above to clarify that pointcuts don't know about advice objects, and advice objects don't
know about pointcuts. Some object somewhere, however, must know about both if we are going to have any hope of wrapping
our beans in aspects. That is where implementations of
PointcutAdvisor
come in. Conceptually speaking, a
PointcutAdvisor
is nothing more than a pointcut and an advice object combined - hence the name. The most
basic variety of pointcut advisor is the
org.springframework.aop.support.DefaultPointcutAdvisor
class.
This is for the most part just a bean that has two references - something akin to this:
Yes, yes, in reality it is more complicated than this - but really that is the bulk of it right there. Now we are getting
to a point where we can define the *what* (the Advice) and the *where* (the Pointcut) in one discrete location. A basic
configuration of this advisor in a spring bean definition may look something like this:
<!--
A simple name matching pointcut that will consider all methods named 'handleRequestInternal'
as joinpoints
-->
<bean name="controller.handle.pointcut" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedName" value="handleRequestInternal"/>
</bean>
<!-- A simple MethodInterceptor style advice object (InterceptorA implements MethodInterceptor) -->
<bean name="interceptorA" class="com.javalobby.tnt.spring.aop.InterceptorA" />
<!-- A simple MethodBeforeAdvice style advice object (BeforeAdviceA implements MethodBeforeAdvice) -->
<bean name="beforeAdviceA" class="com.javalobby.tnt.spring.aop.BeforeAdviceA"/>
<!-- A pointcut advisor that combines the controller pointcut with interceptor A -->
<bean name="pointcut.advisor1" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="interceptorA"/>
<property name="pointcut" ref="controller.handle.pointcut"/>
</bean>
<!--
An alternative pointcut advisor that combines the before advice with the controller pointcut
Showing how reuse of pointcuts and advices is possible
-->
<bean name="pointcut.advisor2" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="beforeAdviceA"/>
<property name="pointcut" ref="controller.handle.pointcut"/>
</bean>
Hopefully this gives you some idea of the relationship of these three classes. As you can see,
advice objects and pointcuts can be intermixed freely into varying pointcut advisors.
Let's Simplify Things
Ok, now, throw all of that example out of the window. Why? Well, because in reality while the above example
is much more flexible, it is quite verbose as well. Most times that level of granularity is unnecessary, as
we will soon see. Earlier I glossed over the
org.springframework.aop.support.PointcutAdvisor
class hierarchy, and just mentioned the most basic
DefaultPointcutAdvisor
. Let's take a closer
look at the available class hierarchy now:
Did you notice how similar the names are to the pointcuts we just learned about? Most of these classes take
the seperation of pointcut and advisor out of the equation, which, while theoretically reducing some degree of
flexibility, typically makes configuration much easier. Here is the same example above, using the
NameMatchMethodPointcut
Advisor
object (which combines the
PointcutAdvisor
API
with the
NameMatchMethodPointcut
class):
<!-- A simple MethodInterceptor style advice object (InterceptorA implements MethodInterceptor) -->
<bean name="interceptorA" class="com.javalobby.tnt.spring.aop.InterceptorA" />
<!-- A simple MethodBeforeAdvice style advice object (BeforeAdviceA implements MethodBeforeAdvice) -->
<bean name="beforeAdviceA" class="com.javalobby.tnt.spring.aop.BeforeAdviceA"/>
<!--
Use the NameMatchMethod pointcut advisor to make things a little simpler.
-->
<bean name="pointcut.advisor1" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="interceptorA"/>
<property name="mappedName" value="handleRequestInternal"/>
</bean>
<!--
Use the NameMatchMethod pointcut advisor to make things a little simpler.
-->
<bean name="pointcut.advisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="beforeAdviceA"/>
<property name="mappedName" value="handleRequestInternal"/>
</bean>
As you can see, we got rid of the configuration of one bean entirely. Technically speaking we are no longer
reusing the pointcut, but since pointcut definitions are typically a configuration concern (as seen above), it
doesn't usually matter one way or another to us.
Gluing it All Together
So, we've covered advice objects and pointcut objects - which when you get down to it, are the core; the center of Spring
AOP support. Then we covered pointcut advisors which take advice objects and pointcut objects and glue them together into
one cohesive chunk - the peanut butter and jelly; the meat and potatoes; the spaghetti and meatballs; the lamb and tunafish.
There is a very important piece of the puzzle missing however: how do we wrap these pointcut-advisor combos around our objects?
After all, that is the whole point of all of this. Enter the
ProxyFactoryBean
.
Without getting into too much detail, Spring supports the concept of a
FactoryBean
, which is a special type
of bean, in that the bean returned is a factory result, rather than just a plain 'newInstance()' call on the class you
provided. So, you could have a factory bean implementation that, based on certain configuration details, factoried different
implementations of a certain class. So, just to solidify my point, in this example:
If you ask for
myBean
from the bean factory, you're *not* going to get an instance of
MyFactoryBean
-
instead, Spring is going to consult with the
MyFactoryBean
object, and ask it to provide the object you want.
Why is all of this important? Well, because this
FactoryBean
concept is how Spring wraps your beans - via the
some configuration details, and then using some internal tool (dynamic proxies, CGLib, etc.) to create a proxy for
your bean that executes some advice on method calls when the pointcut says the method is a joinpoint (assuming a pointcut
is defined).
Expanding our example above, here is how Spring's proxy factory bean works:
<!-- A simple MethodInterceptor style advice object (InterceptorA implements MethodInterceptor) -->
<bean name="interceptorA" class="com.javalobby.tnt.spring.aop.InterceptorA" />
<!-- A simple MethodBeforeAdvice style advice object (BeforeAdviceA implements MethodBeforeAdvice) -->
<bean name="beforeAdviceA" class="com.javalobby.tnt.spring.aop.BeforeAdviceA"/>
<!--
Use the NameMatchMethod pointcut advisor to make things a little simpler.
-->
<bean name="pointcut.advisor1" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="interceptorA"/>
<property name="mappedName" value="handleRequestInternal"/>
</bean>
<!--
Use the NameMatchMethod pointcut advisor to make things a little simpler.
-->
<bean name="pointcut.advisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="beforeAdviceA"/>
<property name="mappedName" value="handleRequestInternal"/>
</bean>
<!-- Create our controller bean -->
<bean name="myRawController" class="com.javalobby.tnt.spring.aop.ExampleController" />
<!-- Create the proxy bean that returns AOP'd varieties of our controller -->
<bean name="myController" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>pointcut.advisor2</value>
<value>pointcut.advisor1</value>
<value>myRawController</value>
</list>
</property>
</bean>
Notice the
interceptorNames
property? This is how we tell the proxy factory bean what advisors or advice
objects we want to apply to the proxied bean. Order is important in this list - the order the advisors or advice objects
are entered in the list defines the order they will be invoked when entering and exiting the bean.
Note that in this case the *last* entry in the list is our bean
that we want to be proxied. This is just one possible way to define the bean to be proxied as we'll see in a
moment. Also, did you notice that I said
advisors or advice objects
? That is because the proxy
factory bean allows for another shortcut; not specifying a pointcut at all, just an advice. In those cases, an
'every method is a joinpoint' style pointcut will automatically be applied. So, if we didn't care which methods
were advised, we could shorten the example above like this:
Now, I mentioned earlier that there is another way to specify the target bean. This can be done through the
targetName
and/or
target
properties on the factory bean:
<!-- Create the proxy bean that returns AOP'd varieties of our controller -->
<bean name="myController" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="myRawController"/>
<property name="interceptorNames">
<list>
<value>beforeAdviceA</value>
<value>interceptorA</value>
</list>
</property>
</bean>
If you don't need direct (non-AOP'd) access to your bean, then it may be better for the simplicity of the file
to just use an anonymous inner bean, rather than declaring the bean seperately to the proxy:
<!-- Create the proxy bean that returns AOP'd varieties of our controller -->
<bean name="myController" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><bean class="com.javalobby.tnt.aop.ExampleController"/></property>
<property name="interceptorNames">
<list>
<value>beforeAdviceA</value>
<value>interceptorA</value>
</list>
</property>
</bean>
Conclusion for Now
Ok, well, I could keep going on and on and on, but I'd never finish this article, and you'd never get to read it;
and if you *did*, it'd be so long and boring that I might as well put it on the shelf next to the encyclopedia.
Now, some people who already know about Spring AOP are probably ready to clamor because I haven't covered these
topics (among others I'm sure):
Introductions/Mixins
Specialized Proxy Support (such as the TransactionProxyFactoryBean)
Other corner cases
I didn't cover introductions specifically because they are so uniquely different from other types of Spring AOP, I thought it would
be good to cover the basic, common forms first. As far as the specialized cases and 'unique tweaks', let's gauge the
popularity of the subject, and see where we get.
I'm looking forward to your feedback, questions, and comments on whether or not you want more tips on this subject!
It's a fantastic effort for those guys who are just started learning spring. I hope the author will provide more light on the other topis of spring also.
This is one of the best articles I have read on a complex subject put across so neatly. Full ***** for the efforts!
However it took me roughly 2 n half hours to read/reread and understand the whole article. Partially because I had the aop.alliance & spring.aop class diagrams with me and was comparing them with your initial explanation.
These are some improvements you can make to the article:-
- please give recommendations to understand the class diagram of aop.alliance in the very first beginning. It is easier to understand the concepts once the reader gets to know the hierarchy of Advice, Interceptor, Invocation, JointPoint etc in parallel to your article. Without the class diagram most of the explanation looks confusing.
- Even after reading your definition of "advice" and the javadoc on "advice" which says - "Implementations can be any type of advice, such as Interceptors"; it is still still unclear the distinction between an advice and an Interceptor. Right now Interceptor seems to be the only "kind of" Advice. Can you suggest what could possibly be another *kind of* Advice? I'm looking for an Interface in the same level as Interceptor. Currently there is none in aop as well as Spring package. So its not sure what the scope of Advice could be and the reason for the subinterface, Interceptor
- A subsequent article in the section on Introduction would be of great help.
- Would appreciate if you could come up with a similar style article substantiating the concept of Dynamic Proxy which could complete the tutorial on AOP. currently you have assumed the reader to be knowing Dynamic proxies. (you could fill this space as well)
A well articulated article on AOP for beginners. It gave me a lot of insight as a beginner. Thanks for the article.
I have a problem with using AOP, in that I can't figure out how to intercept individual methods inside my Controller. For instance I have 10 different action methods inside my MultiActionController. All I can intercept is handleRequest() not beyond that.
Though I have an interface for the methods in the MultiActionController and pass it as an argument to the ProxyInterfaces while creating Proxy. Still it does' not recognize my methods.
Is that something that I am missing here seriously. Do you have any example that I can refer for applying Advices to methods inside Controller.
I would like to pointout a mistake, if i am not wrong,
under the section "Static vs. Dynamic Method Matching", i got confused with the class you extended for Dynamic matching pointcut. I think it should be 'DynamicMethodMatcherPointCut' and the method signature for matches should be matches(Method,Class). The sameway the method signature for StaticMethodMatcherPointCut::matches() should be matches(Method,Class,Object[]).
I am having the exact same problem. It only seems to intercept handleRequest() in the Controller interface but not my methods. I tried to break it out into my own interface and put that in the interceptorNames but no avail.
This article about Spring AOP helped me a lot. Now i'm able to have the understanding about pincuts.Before that i was bit confuse about what the purpose of pincuts is.
Thanks.
There certainly have been performance issues with Java.
We've been working really hard on them.
The primary way we've attacked the problem is with advanced virtual machines. The performance
has been getting very nice. --James Gosling, 1999.
I was reading the reference from Spring, and there are too much details in it. It is hard to understand the basic of AOP. Then I found this article, it explained the AOP basic very clearly.
I also created a Java project following the code in this article. Everything works fine except that it doesn;t mention that I need to configure proxyInterfaces when I configure the ProxyFactoryBean. I run into error related to missing CGLIB kind of error when I run the program. I added following property to ProxyFactoryBean:
<!-- <property name = "proxyInterfaces"><value>aop.IController</value></property> -->
Spring: A Quick Journey Through Spring AOP
At 12:22 PM on Aug 31, 2005, R.J. Lorimer wrote:
Fresh Jobs for Developers Post a job opportunity
One of the strengths of the Spring Framework is its robust and flexible aspect oriented programming infrastructure. In Spring, AOP is a little different than other AOP frameworks in that it brings with it a consistent AOP infrastructure that can be applied for other AOP technical solutions. Out of the gate, Spring supports dynamic-proxy-based AOP, and CGLib-based AOP. Both of these have their limitations, but can honestly be used in a very large majority of cases. Spring does have integration support with AspectJ as well, however, so don't worry. Thankfully, the AspectJ integration is not drastically different from the regular AOP, which I think shows some of the strengths of Spring's AOP infrastructure; even an AOP library as different as AspectJ can still be integrated.
General Education
Spring's 'built-in' AOP infrastructure is defined by the
org.springframework.aop.*packages. To understand the packages, you have to have at least some idea of the concepts of AOP as Spring models these concepts *very* closely in implementation, so I'll explain them. Now... every article I read on AOP seems to just try to confuse me - and the vocabulary around AOP even makes it worse. I'm going to do my best to describe things as simply as possible, so bear with me:Spring and Advice Objects
I like to start with the concept of advice objects, because they are the easiest to bridge to from a non-AOP way of thinking, because an advice is really very similar to a decorator (as I mentioned above). Advice implementations in Spring are simply implementations of the
org.aopalliance.intercept.MethodInterceptorinterface. Woah! Wait a minute - that's not a Spring class! Nope - it turns out that Spring's AOP implementation uses a *standard* AOP API from the AOP Alliance, which you can read more about here . TheMethodInterceptorinterface is actually a child of theorg.aopalliance.intercept.Interceptorinterface, which is a child of another interface,org.aopalliance.aop.Advice- Whew!. Remember that I said Spring AOP only supports method invocation, but that conceptually, an advice could include field access, constructor invocation and a bunch of other things. That is why Spring's advice starts at theMethodInterceptorinterface, even though there are other interfaces higher up - because MethodInterceptor is the sub-interface that is designed for method-invocation style advice and for which Spring has support. TheMethodInterceptorinterface is really quite simple:public interface MethodInterceptor extends Interceptor { Object invoke(MethodInvocation invocation) throws Throwable; }Basically, when you write an advice for intercepting a method, you have to implement one method - the
invokemethod, and you are given aMethodInvocationobject to work with. TheMethodInvocationobject tells us a bunch of stuff about the method that we're intercepting, and also gives a hook to tell the method to go ahead and run.Let's jump right in and look at a (very) basic method performance profiling advice:
import org.aopalliance.intercept.*; public class PerformanceInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation method) throws Throwable { long start = System.currentTimeMillis(); try { Object result = method.proceed(); return result; } finally { long end = System.currentTimeMillis(); long timeMs = end - start; System.out.println("Method: " + method.toString() + " took: " + timeMs +"ms."); } } }Not too complicated really - just capture the time before the method invocation, tell the method to go ahead and run, then afterward capture the time again, calculate the difference, and print it out. Incidentally, Spring already has a better implementation of this type of interceptor - the
org.springframework.aop.interceptor.PerformanceMonitorInterceptor- there are actually quite a few useful concrete interceptor implementations in there - check it out.Spring has multiple alternatives to the basic
MethodInterceptor, however, (which is referred to in the Spring documentation as an 'around' advice) so that if you want to do more specific things, you can with less complication - these extensions come in the form of Spring-specific extensions to theAdviceinterface (siblings to theMethodInterceptorinterface), and they include:You'll notice in this case you aren't given the
MethodInvocationobject, just the underlyingMethodobject - this is because the call to
proceed()will be handled by Spring for you; all you need to do isdo what you need *before* the method is called (as the interface name implies).
MethodBeforeAdvice.This interface's method will be called on the return from the invocation of a method. The contract looks like this:
You'll notice it looks a whole like the before advice, but simply adds the Object's return value to the
method arguments.
to implement a particular contract, this is simply a 'marker' interface, and expects you to implement any number
of methods that look like this:
Oddly enough, the only mandatory argument is the
Throwablesub-type.Here is a snapshot that generally covers the 'advice' hierarchy:
That's a primer on advice objects. Not too bad so far, right? If you've ever worked with in reflection in Java, most of this is fairly similar in style.
Spring and Pointcuts
What seperates AOP from object-oriented design patterns such as the decorator pattern, at least when talking about Spring AOP, is the fact that the *what* is defined seperately from the *where* (or would it be *whom*?). In other words, the 'advice', which is the code to be invoked, is disconnected entirely from the particular item it is 'advising' - which, again, in the Spring case is always a method. In other words, an advice in Spring doesn't have any association, type binding, dependency, or any other form of direct awareness of the method it is working with.
Remember that the thing that an advice works with is called a
JoinPoint. Our join points in Spring are always methods, and at runtime resolve toorg.aopalliance.aop.Methodobjects which have made appearances as method arguments to our advices above. To solidify the point,org.aopalliance.aop.Methodextendsorg.aopalliance.aop.JoinPoint.The reason I am bringing joinpoints back up is because a
Pointcutobject is all about defining all of the joinpoints that an advice should be 'applied to'. In Spring terms, a pointcut defines all of the methods that our interceptor should intercept. Pointcuts in Spring implement theorg.springframework.aop.Pointcutinterface and look something like this:package org.springframework.aop; public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); }The class filter is a special type of object that describes which classes have potential joinpoints (read methods) on them. The method matcher simply describes which methods for a given class are considered valid joinpoints for this pointcut. I don't want to spend too much time on the pointcut interface, however, because chances are - you won't be implementing it.
Static vs. Dynamic Method Matching
Spring makes a distinction between static and dynamic method matching. A static method matching pointcut (a subclass of the
org.springframework.aop.support.StaticMethodMatcherPointcutclass) knows at the time it proxies a target object what methods it considers joinpoints on that object. A dymamic method matching pointcut (see below for implementation details), on the other hand must be consulted at *every* method invocation. This is a useful implementation detail because a static method matcher, while having less flexibility (you can't check the method invocation arguments), is, by design, much faster, as the check is only performed once, rather than at every method invocation. Static Matching pointcuts implementations look something like this:public class MyBeanPointcut extends StaticMethodMatcherPointcut { public boolean matches(java.lang.reflect.Method theMethod, java.lang.Class theClass) { return (MyBean.class.isAssignableFrom(theClass) && theMethod.equals(...)); } }In most cases, however, this is irrelevant, because there is a very convenient pair of static method matchers that cover almost all concerns - the
org.springframework.aop.support.JdkRegexpMethodPointcutandorg.springframework.aop.support.PerlRegexpMethodPointcutclasses. You typically configure these outside of your code (we'll get to configuration in a bit), and don't have to do any nasty reflection checks as seen above. In addition, there is a simpler variety of text-based matching called theNameMatchedMethodPointcut- which is similar to the regex implementations, but only matches exact names.Dynamic matching pointcut implementations typically look something like this:
public class MyBeanPointcut extends StaticMethodMatcherPointcut { public boolean matches(java.lang.reflect.Method theMethod, java.lang.Class theClass, Object[] arguments) { boolean matches = false; if(MyBean.class.isAssignableFrom(theClass) && theMethod.equals(...)) { if(arguments[0].equals("Joe Smith")) { matches = true; } } return matches; } }Due to the nature of dynamic pointcuts, there are no real convenience implementations of this class. Here is what the pointcut hierarchy generally looks like:
You may have noticed, neither of my pointcut examples made any reference to any advice (e.g.
MethodInterceptorimplementation) - remember that I said an advice knows the *what*, not the *where*? Well, a pointcut is the inverse - it knows the *where*, not the *what*. Therefore, theoretically, these two components can be intermingled in different configurations and reused.Tying Pointcuts with Advisors - PointcutAdvisors
I've gone to great lengths above to clarify that pointcuts don't know about advice objects, and advice objects don't know about pointcuts. Some object somewhere, however, must know about both if we are going to have any hope of wrapping our beans in aspects. That is where implementations of
PointcutAdvisorcome in. Conceptually speaking, aPointcutAdvisoris nothing more than a pointcut and an advice object combined - hence the name. The most basic variety of pointcut advisor is theorg.springframework.aop.support.DefaultPointcutAdvisorclass. This is for the most part just a bean that has two references - something akin to this:public class DefaultPointcutAdvisor { private Pointcut pointcut; private Advice advice; public Pointcut getPointcut() { return pointcut; } public Advice getAdvice() { return advice; } public void setPointcut(Pointcut pc) { pointcut = pc; } public void setAdvice(Advice a) { advice = a; } }Yes, yes, in reality it is more complicated than this - but really that is the bulk of it right there. Now we are getting to a point where we can define the *what* (the Advice) and the *where* (the Pointcut) in one discrete location. A basic configuration of this advisor in a spring bean definition may look something like this:
Hopefully this gives you some idea of the relationship of these three classes. As you can see, advice objects and pointcuts can be intermixed freely into varying pointcut advisors.
Let's Simplify Things
Ok, now, throw all of that example out of the window. Why? Well, because in reality while the above example is much more flexible, it is quite verbose as well. Most times that level of granularity is unnecessary, as we will soon see. Earlier I glossed over the
org.springframework.aop.support.PointcutAdvisorclass hierarchy, and just mentioned the most basicDefaultPointcutAdvisor. Let's take a closer look at the available class hierarchy now:Did you notice how similar the names are to the pointcuts we just learned about? Most of these classes take the seperation of pointcut and advisor out of the equation, which, while theoretically reducing some degree of flexibility, typically makes configuration much easier. Here is the same example above, using the
NameMatchMethodPointcut Advisorobject (which combines thePointcutAdvisorAPI with theNameMatchMethodPointcutclass):As you can see, we got rid of the configuration of one bean entirely. Technically speaking we are no longer reusing the pointcut, but since pointcut definitions are typically a configuration concern (as seen above), it doesn't usually matter one way or another to us.
Gluing it All Together
So, we've covered advice objects and pointcut objects - which when you get down to it, are the core; the center of Spring AOP support. Then we covered pointcut advisors which take advice objects and pointcut objects and glue them together into one cohesive chunk - the peanut butter and jelly; the meat and potatoes; the spaghetti and meatballs; the lamb and tunafish. There is a very important piece of the puzzle missing however: how do we wrap these pointcut-advisor combos around our objects? After all, that is the whole point of all of this. Enter the
ProxyFactoryBean.Without getting into too much detail, Spring supports the concept of a
FactoryBean, which is a special type of bean, in that the bean returned is a factory result, rather than just a plain 'newInstance()' call on the class you provided. So, you could have a factory bean implementation that, based on certain configuration details, factoried different implementations of a certain class. So, just to solidify my point, in this example:If you ask for
myBeanfrom the bean factory, you're *not* going to get an instance ofMyFactoryBean- instead, Spring is going to consult with theMyFactoryBeanobject, and ask it to provide the object you want.Why is all of this important? Well, because this
FactoryBeanconcept is how Spring wraps your beans - via the some configuration details, and then using some internal tool (dynamic proxies, CGLib, etc.) to create a proxy for your bean that executes some advice on method calls when the pointcut says the method is a joinpoint (assuming a pointcut is defined).Expanding our example above, here is how Spring's proxy factory bean works:
Notice the
interceptorNamesproperty? This is how we tell the proxy factory bean what advisors or advice objects we want to apply to the proxied bean. Order is important in this list - the order the advisors or advice objects are entered in the list defines the order they will be invoked when entering and exiting the bean. Note that in this case the *last* entry in the list is our bean that we want to be proxied. This is just one possible way to define the bean to be proxied as we'll see in a moment. Also, did you notice that I said advisors or advice objects ? That is because the proxy factory bean allows for another shortcut; not specifying a pointcut at all, just an advice. In those cases, an 'every method is a joinpoint' style pointcut will automatically be applied. So, if we didn't care which methods were advised, we could shorten the example above like this:Now, I mentioned earlier that there is another way to specify the target bean. This can be done through the
targetNameand/ortargetproperties on the factory bean:If you don't need direct (non-AOP'd) access to your bean, then it may be better for the simplicity of the file to just use an anonymous inner bean, rather than declaring the bean seperately to the proxy:
Conclusion for Now
Ok, well, I could keep going on and on and on, but I'd never finish this article, and you'd never get to read it; and if you *did*, it'd be so long and boring that I might as well put it on the shelf next to the encyclopedia.
Now, some people who already know about Spring AOP are probably ready to clamor because I haven't covered these topics (among others I'm sure):
I didn't cover introductions specifically because they are so uniquely different from other types of Spring AOP, I thought it would be good to cover the basic, common forms first. As far as the specialized cases and 'unique tweaks', let's gauge the popularity of the subject, and see where we get.
I'm looking forward to your feedback, questions, and comments on whether or not you want more tips on this subject!
Until next time,
R.J. Lorimer
Contributing Editor -rj -at- javalobby.orgAuthor -http://www.coffee-bytes.comSoftware Consultant -http://www.crosslogic.com17 replies so far (
Post your own)
Re: Spring: A Quick Journey Through Spring AOP
Thank you for the tour !I did not know much about Spring. This is a wuite good overview. I like AOP so I will keep a eye on this now.
Re: Spring: A Quick Journey Through Spring AOP
It's a fantastic effort for those guys who are just started learning spring. I hope the author will provide more light on the other topis of spring also.Re: Spring: A Quick Journey Through Spring AOP
Thanks! Well-written and very useful article, on a hot topic.-Walter Gillett
Re: Spring: A Quick Journey Through Spring AOP
This is one of the best articles I have read on a complex subject put across so neatly. Full ***** for the efforts!However it took me roughly 2 n half hours to read/reread and understand the whole article. Partially because I had the aop.alliance & spring.aop class diagrams with me and was comparing them with your initial explanation.
These are some improvements you can make to the article:-
- please give recommendations to understand the class diagram of aop.alliance in the very first beginning. It is easier to understand the concepts once the reader gets to know the hierarchy of Advice, Interceptor, Invocation, JointPoint etc in parallel to your article. Without the class diagram most of the explanation looks confusing.
- Even after reading your definition of "advice" and the javadoc on "advice" which says - "Implementations can be any type of advice, such as Interceptors"; it is still still unclear the distinction between an advice and an Interceptor. Right now Interceptor seems to be the only "kind of" Advice. Can you suggest what could possibly be another *kind of* Advice? I'm looking for an Interface in the same level as Interceptor. Currently there is none in aop as well as Spring package. So its not sure what the scope of Advice could be and the reason for the subinterface, Interceptor
- A subsequent article in the section on Introduction would be of great help.
- Would appreciate if you could come up with a similar style article substantiating the concept of Dynamic Proxy which could complete the tutorial on AOP. currently you have assumed the reader to be knowing Dynamic proxies. (you could fill this space as well)
Once again, brilliant article!
Re: Spring: A Quick Journey Through Spring AOP
Thanks for the very constructive feedback!Here is an article on introduction and mixins.
http://www.javalobby.org/forums/thread.jspa?messageID=91923682
I took the bait in the replies, so you'll have to excuse that heated discussion.
I will make a point to work on updating the article and referencing the follow up.
Thanks again!
Re: Spring: A Quick Journey Through Spring AOP
Good Journey.it push me close to AOP.
Re: Spring: A Quick Journey Through Spring AOP
I think the above link doesnt work!Also, would appreciate if you could clarify the seperation between an advice and an Interception
Re: Spring: A Quick Journey Through Spring AOP
A well articulated article on AOP for beginners. It gave me a lot of insight as a beginner. Thanks for the article.I have a problem with using AOP, in that I can't figure out how to intercept individual methods inside my Controller. For instance I have 10 different action methods inside my MultiActionController. All I can intercept is handleRequest() not beyond that.
Though I have an interface for the methods in the MultiActionController and pass it as an argument to the ProxyInterfaces while creating Proxy. Still it does' not recognize my methods.
Is that something that I am missing here seriously. Do you have any example that I can refer for applying Advices to methods inside Controller.
Thanks Again,
Sathiya
Re: Spring: A Quick Journey Through Spring AOP
Its a nice article about Spring AOP.I would like to pointout a mistake, if i am not wrong,
under the section "Static vs. Dynamic Method Matching", i got confused with the class you extended for Dynamic matching pointcut. I think it should be 'DynamicMethodMatcherPointCut' and the method signature for matches should be matches(Method,Class). The sameway the method signature for StaticMethodMatcherPointCut::matches() should be matches(Method,Class,Object[]).
I think it make sence in doing so.
Thanks
Re: Spring: A Quick Journey Through Spring AOP
I am having the exact same problem. It only seems to intercept handleRequest() in the Controller interface but not my methods. I tried to break it out into my own interface and put that in the interceptorNames but no avail.Has anyone solve this problem?
thanks,
JT
Re: Spring: A Quick Journey Through Spring AOP
This article about Spring AOP helped me a lot. Now i'm able to have the understanding about pincuts.Before that i was bit confuse about what the purpose of pincuts is.Thanks.
Re: Spring: A Quick Journey Through Spring AOP
I was reading the reference from Spring, and there are too much details in it. It is hard to understand the basic of AOP. Then I found this article, it explained the AOP basic very clearly.I also created a Java project following the code in this article. Everything works fine except that it doesn;t mention that I need to configure proxyInterfaces when I configure the ProxyFactoryBean. I run into error related to missing CGLIB kind of error when I run the program. I added following property to ProxyFactoryBean:
<!-- <property name = "proxyInterfaces"><value>aop.IController</value></property> -->
Re: Spring: A Quick Journey Through Spring AOP
Thanks a lot, well constructed document hoping to c more article from the authorRe: Spring: A Quick Journey Through Spring AOP
Great totorial,Now I'm clear on the Spring AOP.I hope you can wirite a book for this content.