Here's my little exploration to Spring's AOP framework - a little interceptor which just logs which class is called and which method is called, plus logging the method invocation time; however I hope this can help others to understand Spring's AOP and help them to write interceptors of their own.
-cptechno
An interceptor used in Spring need to implement the
org.aopalliance.intercept.MethodInterceptor
interface, which requires implementing this method:
public
Object invoke(MethodInvocation methodInvocation)
throws
Throwable;
|
And next, comes that little interceptor...
import
org.aopalliance.intercept.MethodInterceptor;
import
org.aopalliance.intercept.MethodInvocation;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
public class
MyInterceptor
implements
MethodInterceptor
{
private final
Log logger = LogFactory.getLog(getClass());
public
Object invoke(MethodInvocation methodInvocation)
throws
Throwable
{
logger.info(
"Beginning method: "
+ methodInvocation.getMethod().getDeclaringClass() +
"::"
+ methodInvocation.getMethod().getName());
long
startTime = System.currentTimeMillis();
try
{
Object retVal = methodInvocation.proceed();
return
retVal;
}
finally
{
logger.info(
"Ending method: "
+ methodInvocation.getMethod().getDeclaringClass() +
"::"
+ methodInvocation.getMethod().getName());
logger.info(
"Method invocation time: "
+ (System.currentTimeMillis() - startTime) +
" msecs."
);
}
}
}
|
You can do anything as you like; but pay attention to these two lines:
Object retVal = methodInvocation.proceed();
return
retVal;
|
The execution sequence is as follows:
-
Any statements placed before
Object retVal = methodInvocation.proceed();
-
Object retVal = methodInvocation.proceed();
, which gives control to the next interceptor in the interceptor stack, or the underlying method.
-
Any statements placed before
return retVal;
-
return retVal;
, which returns control to the interceptor above it, or exit the whole interceptor stack.
Next, to use the interceptor we wrote, we need to turn our business object as an AOP target, like this:
<bean id=
"SearchBookBeanTarget"
class
=
"library.SearchBookBeanImpl"
init-method=
"init"
/>
|
As shown, we just need to change the bean's id.
Next we need to hang the interceptor on to Spring's ApplicationContext.
<bean id=
"myInterceptor"
class
=
"library.MyInterceptor"
/>
|
And the last step, we declare our business object actually in the ApplicationContext, via its interface we defined, via Spring's ProxyFactoryBean.
<bean id=
"SearchBookBean"
class
=
"org.springframework.aop.framework.ProxyFactoryBean"
>
<property name=
"proxyInterfaces"
><value>library.SearchBookBean</value></property>
<property name=
"interceptorNames"
>
<list>
<value>myInterceptor</value>
<value>SearchBookBeanTarget</value>
</list>
</property>
</bean>
|
-
proxyInterfaces: the actual business interface of our business object.
-
interceptorNames: the execution sequence of the interceptors, with the business object's target as the end of the list. Remember to put the business object's target on the list, otherwise your business object will not work; on the other hand you'll receive an exception telling you that all interceptors had been invoked.
On the application code that will access the business object, no changes are necessary.
Then at your logging target (console, file, etc...) you can see the following output similar to this (time and level info trimmed here):
Beginning method:
interface
library.SearchBookBean::searchBook
....
(log messages about library.SearchBookBean.searchBook()....)
....
Ending method:
interface
library.SearchBookBean::searchBook
Method invocation time:
10
msecs.
|
posted on 2006-09-27 21:07
Warren.Wu 阅读(264)
评论(0) 编辑 收藏