What is aspect?
metrics aspect implements org.jboss.aop.advice.Interceptor.
Interceptor接口含两个方法
String getName()
Object invoke(Invocation invocation) throws Throwable
代码示例1
当调用saveI18nMessage updateI18nMessage方法时,拦截,调用下面invoke方法,针对不同的方法调用(根据方法名字判断是调用了saveI18nMessage 还是调用了updateI18nMessage)然后做相应的处理(获得调用方法的参数然后记录日志)。
private Interceptor metrics = new org.jboss.aop.advice.Interceptor() {
@Override
public String getName() {
return "MessageCommandLogHandleService AOP Interceptor";
}
@Override
public Object invoke(Invocation invocation) throws Throwable {
if (invocation instanceof MethodInvocation) {
MethodInvocation minvocation = (MethodInvocation) invocation;
if(log.isDebugEnabled()){
log.debug("Entering method: " + minvocation.getMethod());
}
String method_nm = minvocation.getMethod().getName();
Object[] args = minvocation.getArguments();
String command = "do nothing";
if (args != null && args[0] instanceof CenterI18nMessageBO) {
CenterI18nMessageBO msgbo = (CenterI18nMessageBO)args[0];
if ("saveI18nMessage".equals(method_nm)) {
command = "save";
msgcmdlog.info(updateLogging(command, msgbo));
} else if ("updateI18nMessage".equals(method_nm)) {
command = "update";
msgcmdlog.info(updateLogging(command, msgbo));
}
}
}
return invocation.invokeNext();
}
};
invoke方法是如何被调用执行的?what is Invocation? Invocation的invokeNext()又做了些什么?
从invoke的参数Invocation对象中能够获取被调用方法的名字和传入的参数值等信息。
java.lang.reflect.Method method = (MethodInvocation)invocation.getMethod();
在上面代码中从Invocation对象中获得被调用方法的contextual infomation。refect.Method
从下面(摘自jbossaop_userguide.pdf)可以简要看出Invocation类的作用以及AOP framework的处理过程(1.将被调用方法break into parts,形象的理解为dissect解剖,封装在Invocation对象中 2.由framework来控制调用位于calling code和被调用方法间的某某aspects)。
这里的Metrics是Interceptor接口的实现类,为什么称Interceptor接口的实现类为Metrics呢?metrics是衡量指标的意思,比如测量一个方法执行所花销的时间就可以理解为metrics,当然还可以是将一个方法的调用记录在日志等等这些与业务逻辑没有关系的附加方法。withdraw应该就是那个要被拦截的方法。
Invocation的invokeNext() wraps and delegates to the actual method. 实现原理
return invocation.invokeNext()是否要放在try{}finally{}里。
When to execute the aspect code?
-->define by pointcut
a pointcut expression matches events/points within your application。
What pointcut expression to do?
define various points/events in java application so that you can apply your aspects.
一个合法的pointcut可以定义如:对于任何对JDBC中的executeQuery()方法的调用,都会调用aspect来验证SQL语法。
entry point :field access、method call、constructor call。
events:exception throw。
How to define a pointcut?
xml定义
annotation定义
JBoss AOP basic terms
应用中哪些地方(point)会需要拦截(方法调用、构造执行、属性访问)? -- Joinpoint
这些point在runtime时封装在哪里? -- Invocation
描述某个具体(范围)的点? --Pointcut
当这些点的执行被触发时,由什么去负责处理? --Advice
抽象这种Advice规范? -- 定义Interceptor接口,声明invoke()
定义了若干个advice,若干个pointcut。 --Aspect
org.jboss.aop.advice
-接口Interceptor:invoke( )
-类AdviceBinding
代码示例2
Interceptor logInterceptor = new Interceptor() {
@Override
public String getName() {
return "";
}
@Override
public Object invoke(Invocation invocation) throws Throwable{
.....
}
} //Interceptor
InstanceInterceptorFactory factory = new InstanceInterceptorFactory(logInterceptor); //
String AOPBindingExpr =
"execution(* com.wxxr.common.service.i18nmessagemgr.CenterI18nMessageService-> saveI18nMessage(..))"; //pointcut
AdviceBinding binding = new AdviceBinding(AOPBindingExpr, null);
binding.addInterceptorFactory(factory);
AspectManager.instance().addBinding(binding);
其中InstanceInterceptorFactory类如下:
package com.wxxr.common.jboss.aop;
import org.jboss.aop.Advisor;
import org.jboss.aop.advice.AspectDefinition;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.advice.InterceptorFactory;
import org.jboss.aop.joinpoint.Joinpoint;
public class InstanceInterceptorFactory implements InterceptorFactory
{
private Interceptor interceptor;
public InstanceInterceptorFactory(Interceptor interceptor)
{
this.interceptor = interceptor;
}
@Override
public Interceptor create(Advisor advisor, Joinpoint joinpoint)
{
return interceptor;
}
public String getClassName()
{
return interceptor.getClass().getName();
}
@Override
public String getAdvice()
{
return "invoke";
}
@Override
public AspectDefinition getAspect()
{
return null;
}
@Override
public String getName()
{
return interceptor.getName();
}
@Override
public boolean isDeployed()
{
return true;
}
}
研究这些类的源码,搞清原理
深入研究
1.Invocation接口及实现类
2.Invocation的invokeNext()