应用场景
公共模块抽象出来,简单的AOP功能编织到模块中
核心技术实现
动态代理,相关的拦截器都配置到了动态对象里
JDK 动态代理
只能代理实现接口的类
invoke里封装了aop的实现
CGLIB 字节码增强技术
可以直接代理类
对callback回调设置中,通过DynamicAdvisedInterceptor拦截器来实现AOP功能的
源码解析
以JDK动态代理为例
JdkDynamicAopProxy
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//如果拦截器链为空,直接调用目标方法
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//否则的话,从这里开始调用
retVal = invocation.proceed();
}
}
invocation 这个的实现ReflectiveMethodInvocation 这个类
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//如果拦截器调用完成,则调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//匹配这个方法是不是需要拦截,是的话,调用拦截器
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { //invoke执行拦截器
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
上面有一个问题,从逻辑来看,是调用了所有的拦截器,再调用目标方法,这个时候,有一个疑问,after 通知不是方法执行了,再调用这个拦截操作嘛,继续往下看
before 拦截器的实现 MethodBeforeAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
after的实现 AspectJAfterAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
我们可以看到before和after有可区别的,before先执行拦截,再调用下一步的拦截,after是一直要调用目标方法执行了之后,才执行这个after的逻辑。这后边是递归的逻辑。