容器中保存了组件的代理对象(cglib增强后的对象),这个对象包含了详细信息(目标对象,增强器,等等)
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
Object var16;
try {
if(this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = target != null?target.getClass():null;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
} else {
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
}
retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
var16 = retVal;
} finally {
if(target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if(setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return var16;
}
- CglibAopProxy.intercept();拦截目标对象的方法
- 根据ProxyFactory对象,获取将要执行的目标方法的拦截器链
List< Object > chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 如果没有拦截器链,直接执行目标对象的方法
- 如果存在拦截器链,把需要执行的目标对象、目标方法,拦截器链等信息创建一个CglibMethodInvocation,并调用proceed方法
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
5. 拦截器链的触发过程
@Nullable
public Object proceed() throws Throwable {
if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null?this.targetClass:this.method.getDeclaringClass();
return dm.methodMatcher.matches(this.method, targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
} else {
return
((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
- 如果没有拦截器,直接执行目标方法,或者执行拦截器的索引和拦截器数组-1大小一样
(指定到了最后一个拦截器)执行目标方法 - 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回之后再来执行。通过拦截器链的机制,保证通知方法和目标方法的执行顺序。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/342e835d3f7be7a7d9a3b23623046deb.png)
具体细节
- 使用责任链模式进行执行,依次执行拦截器链中的方法
- 通过索引的不断递增,来执行拦截器链中的所有方法
1 . ExposeInvocationInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
invocation.set(mi);
Object var3;
try {
var3 = mi.proceed();
} finally {
invocation.set(oldInvocation);
}
return var3;
}
currentInterceptorIndex++,执行下一个拦截器的Invoke方法
2. AspectJAfterThrowingAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
} catch (Throwable var3) {
if(this.shouldInvokeOnThrowing(var3)) {
this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
}
throw var3;
}
}
3. AfterReturningAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
4. MethodBeforeAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
5. proceed
- currentInterceptorIndex等于长度减1,所以通过反射来执行目标对象方法,执行完后,递归返回去依次执行 4 3 2 1 中相应的逻辑,最后执行完成。
@Nullable
public Object proceed() throws Throwable {
if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null?this.targetClass:this.method.getDeclaringClass();
return dm.methodMatcher.matches(this.method, targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
} catch (InvocationTargetException var4) {
throw var4.getTargetException();
} catch (IllegalArgumentException var5) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", var5);
} catch (IllegalAccessException var6) {
throw new AopInvocationException("Could not access method [" + method + "]", var6);
}
}
总结
- @EnableAspectJAutoProxy 开启Aop功能
- @EnableAspectJAutoProxy 会给容器中注册一个AnnotationAwareAspectJAutoProxyCreator
- AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
- 容器的创建流程
- registerBeanPostProcessors()注册后置处理器,会创建AnnotationAwareAspectJAutoProxyCreator对象。
- finishBeanFactoryInitialization(),初始化剩下的单实例bean
- 创建业务逻辑组件和切面组件
- AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
- 组件创建完成之后,判断组件是否需要增强
- 如果需要,切面的通知方法,包装成增强器,然后给业务逻辑组件创建代理对象(cglib),代理对象中有目标对象,以及增强器。
- 执行目标方法
- 代理对象执行目标方法
- CglibAopProxy.intercept()执行
- 先获取拦截器链(增强方法)
- 利用拦截器链式机制依次进入每一个拦截器执行
- 效果
- 正常执行:前置通知–》目标方法–》后置通知–》返回通知
- 出现异常:前置通知–》目标方法–》后置通知–》异常通知