Spring注解驱动开发之十四——AOP原理分析(二)Annotation...AutoProxyCreator 实现时机

筅森魡賤 提交于 2020-12-29 19:11:36

本文包含以下内容:

  1. postProcessBeforeInstantiation 执行时机

  2. postProcessBeforeInstantiation  的具体作用

  3. 目标方法div执行流程一:获取拦截器链

  4. 目标方法div执行流程二:拦截器链的调用流程分析

  5. AOP 总结


前文回顾:

Spring注解驱动开发之十三——AOP原理分析(一)@EnableAspectJAutoProxy注解干了什么

上文说到,通过 @EnableAspectJAutoProxy 注解,将通过注册器往Spring中注册一个 AnnotationAwareAspectJAutoProxyCreator 实例化对象,并且讨论了AnnotationAwareAspectJAutoProxyCreator  的继承关系。
本文将紧接上文,进行断点调试在 registerBeanPostProcessors 函数之后讨论, AnnotationAwareAspectJAutoProxyCreator    实例化组件如何实现AOP 的功能。


1.postProcessBeforeInstantiation 执行时机

postProcessBeforeInstantiation  函数添加断点,查看执行时机

调用栈如图所示:
1)<init>:84, AnnotationConfigApplicationContext
refresh:543, AbstractApplicationContext
调用栈跟上文类似,上文,注册了BeanPostProcessors 现在运行 finishBeanFactoryInitialization 函数
根据注释:注册所有剩余得“非懒加载”得单例
// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);
2)进入到内部,是创建Bean 得流程
finishBeanFactoryInitialization:867, AbstractApplicationContext
preInstantiateSingletons:761, DefaultListableBeanFactory
getBean:197, AbstractBeanFactory
doGetBean:302, AbstractBeanFactory
getBean->doGetBean()->getSingleton()
主流程
可以看到 sharedInstance 之前,尝试获取,确认容器内没有才进行创建
// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {  if (logger.isDebugEnabled()) {    if (isSingletonCurrentlyInCreation(beanName)) {      logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +          "' that is not fully initialized yet - a consequence of a circular reference");    }    else {      logger.debug("Returning cached instance of singleton bean '" + beanName + "'");    }  }  bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}
3)getSingleton:230, DefaultSingletonBeanRegistry
getObject:306, AbstractBeanFactory$1
createBean:473, AbstractAutowireCapableBeanFactory
在这里可以看到注释 :让BeanPostProcessors有机会 返回一个代理 而不是原有bean实例。
所以在获取到的Bean  ==null 时在后面将会进行 doCreateBean(beanName, mbdToUse, args); 创建Bean
try {  // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  Object bean = resolveBeforeInstantiation(beanName, mbdToUse);  if (bean != null) {    return bean;  }}catch (Throwable ex) {  throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,      "BeanPostProcessor before instantiation of bean failed", ex);}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'");}
查看函数可以看到,跟上文的 创建Bean 的一样 
实例化Bean
if (instanceWrapper == null) {  instanceWrapper = createBeanInstance(beanName, mbd, args);}
赋值以及初始化
populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {  exposedObject = initializeBean(beanName, exposedObject, mbd);}
4) 进入 resolveBeforeInstantiation 函数
resolveBeforeInstantiation:1011, AbstractAutowireCapableBeanFactory
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {  Object bean = null;  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {    // Make sure bean class is actually resolved at this point.    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {      Class<?> targetType = determineTargetType(beanName, mbd);      if (targetType != null) {        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);        if (bean != null) {          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);        }      }    }    mbd.beforeInstantiationResolved = (bean != null);  }  return bean;}
看到函数 中:
 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);    if (bean != null) {      bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);    }
进入到函数 applyBeanPostProcessorsBeforeInstantiation
查看是否实现InstantiationAwareBeanPostProcessor ,如果是则执行postProcessBeforeInstantiation ,如果返回不为null 则运行applyBeanPostProcessorsAfterInitialization 。所以在这找到了Before 和After
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {  for (BeanPostProcessor bp : getBeanPostProcessors()) {    if (bp instanceof InstantiationAwareBeanPostProcessor) {      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;      Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);      if (result != null) {        return result;      }    }  }  return null;}
从而找到了, postProcessBeforeInstantiation 、applyBeanPostProcessorsAfterInitialization 执行时机 并且得出结论:
AnnotationAwareAspectJAutoProxyCreator  在所有bean创建之前会有一个拦截,InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()

2.postProcessBeforeInstantiation 具体作用
我们分别对自定义得MathCalculator进行断点调试, postProcessBeforeInstantiation 函数代码如下所示。
@Override  public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {    Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } }
// Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. if (beanName != null) { TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { this.targetSourcedBeans.add(beanName); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } }
return null; }
1. MathCalculator ,放行跳转到 MathCalculator 

1.判断是否包含在增强adviseBeans 中
    if (this.advisedBeans.containsKey(cacheKey)) {      return null;    }
2.判断 2个函数判断
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {    this.advisedBeans.put(cacheKey, Boolean.FALSE);    return null;  }
2.1 isInfrastructureClass 判断是不是 Advice、 Pointcut、Adviso r、AopInfras tructureBean 类型
protected boolean isInfrastructureClass(Class<?> beanClass) {  boolean retVal = Advice.class.isAssignableFrom(beanClass) ||      Pointcut.class.isAssignableFrom(beanClass) ||      Advisor.class.isAssignableFrom(beanClass) ||      AopInfrastructureBean.class.isAssignableFrom(beanClass);  if (retVal && logger.isTraceEnabled()) {    logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");  }  return retVal;}
以及 判断是否是切面(@Aspect)
@Override  protected boolean isInfrastructureClass(Class<?> beanClass) {    // Previously we setProxyTargetClass(true) in the constructor, but that has too    // broad an impact. Instead we now override isInfrastructureClass to avoid proxying    // aspects. I'm not entirely happy with that as there is no good reason not    // to advise aspects, except that it causes advice invocation to go through a    // proxy, and if the aspect implements e.g the Ordered interface it will be    // proxied by that interface and fail at runtime as the advice method is not    // defined on the interface. We could potentially relax the restriction about    // not advising aspects in the future.    return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));  }
isAs pect 函数,判断具体是否巨有Aspect.class 这个注解
@Overridepublic boolean isAspect(Class<?> clazz) {  return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));}
private boolean hasAspectAnnotation(Class<?> clazz) { return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);}
2.2  shouldSkip 判断是否应该跳过,获取到所有 Advisor 判断是否实现
AspectJPointcutAdvisor 判断是否跳过
@Overrideprotected boolean shouldSkip(Class<?> beanClass, String beanName) {  // TODO: Consider optimization by caching the list of the aspect names  List<Advisor> candidateAdvisors = findCandidateAdvisors();  for (Advisor advisor : candidateAdvisors) {    if (advisor instanceof AspectJPointcutAdvisor) {      if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {        return true;      }    }  }  return super.shouldSkip(beanClass, beanName);}
 可以断点看到当前,并不是 AspectJPointcutAdvisor 所以直接返回null

接下来会调用 new方法创建实例 


3.然后创建完成后调用postProcessAfterInitialization函数 

/**   * Create a proxy with the configured interceptors if the bean is   * identified as one to proxy by the subclass.   * @see #getAdvicesAndAdvisorsForBean   */  @Override  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {    if (bean != null) {      Object cacheKey = getCacheKey(bean.getClass(), beanName);      if (!this.earlyProxyReferences.contains(cacheKey)) {        return wrapIfNecessary(bean, beanName, cacheKey);      }    }    return bean;  }

看到 wrapIfNecessary 函数,如下

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {  if (beanName != null && this.targetSourcedBeans.contains(beanName)) {    return bean;  }  if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {    return bean;  }  if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {    this.advisedBeans.put(cacheKey, Boolean.FALSE);    return bean;  }
// Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; }
this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean;}

3.1在wrapIfNecessary函数 中,判断targetSourcedBeans 列表里面是否,创建过当前Bean

if (beanName != null && this.targetSourcedBeans.contains(beanName)) {  return bean;}

3.2 判断修饰过的advisedBeans是否包含

if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {  return bean;}

3.3与上面2.1 和2.2相同 判断是否代理,是否跳过

if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {  this.advisedBeans.put(cacheKey, Boolean.FALSE);  return bean;}

3.4接下来判断过后调用getAdvicesAndAdvisorsForBean函数中的findEligibleAdvisors 找到所有的能用的通知方法并进行排序

@Overrideprotected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {  List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);  if (advisors.isEmpty()) {    return DO_NOT_PROXY;  }  return advisors.toArray();}

3.5 将当前Bean 放入advisedBeans 中表示已经被增强处理过并且通过createProxy 获得代理对象 并返回

if (specificInterceptors != DO_NOT_PROXY) {  this.advisedBeans.put(cacheKey, Boolean.TRUE);  Object proxy = createProxy(      bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));  this.proxyTypes.put(cacheKey, proxy.getClass());  return proxy;}

通过代理工厂创建代码如下

protected Object createProxy(    Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); }
ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } }
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); }
return proxyFactory.getProxy(getProxyClassLoader());}

可以看到有CglibAopProxy 和  ObjenesisCglibAopProxy ,然后在容器获取对象时,将会进行返回代理对象。这就是postProcessBeforeInstantiation 具体作用


3.目标方法div执行流程一:获取拦截器链

对容器获取到的对象,添加断点,查看div 目标方法的执行流程

可以看到如下图,所示,mathCalculator 对象是经过Cglib 代理后的对象

1.进入方法可以看到进入CglibAopProxy.intercept() 方法进行代理拦截,代码如下

@Override    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {      Object oldProxy = null;      boolean setProxyContext = false;      Class<?> targetClass = null;      Object target = null;      try {        if (this.advised.exposeProxy) {          // Make invocation available if necessary.          oldProxy = AopContext.setCurrentProxy(proxy);          setProxyContext = true;        }        // May be null. Get as late as possible to minimize the time we        // "own" the target, in case it comes from a pool...        target = getTarget();        if (target != null) {          targetClass = target.getClass();        }        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);        Object retVal;        // Check whether we only have one InvokerInterceptor: that is,        // no real advice, but just reflective invocation of the target.        if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {          // 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 = methodProxy.invoke(target, argsToUse);        }        else {          // We need to create a method invocation...          retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();        }        retVal = processReturnType(proxy, target, method, retVal);        return retVal;      }      finally {        if (target != null) {          releaseTarget(target);        }        if (setProxyContext) {          // Restore old proxy.          AopContext.setCurrentProxy(oldProxy);        }      }    }

2.其核心是通过getInterceptorsAndDynamicInterceptionAdvice函数,获取拦截器列表,判断列表是否为空来进行不同的操作

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);  Object retVal;  // Check whether we only have one InvokerInterceptor: that is,  // no real advice, but just reflective invocation of the target.  if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {    // 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 = methodProxy.invoke(target, argsToUse);  }  else {    // We need to create a method invocation...    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();  }

3.进入获取拦截器列表的函数

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {    MethodCacheKey cacheKey = new MethodCacheKey(method);    List<Object> cached = this.methodCache.get(cacheKey);    if (cached == null) {      cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(          this, method, targetClass);      this.methodCache.put(cacheKey, cached);    }    return cached;  }

4.看到getInterceptorsAndDynamicInterceptionAdvice函数,registry.getInterceptors(advisor);遍历所有的增强器,返回interceptorList

@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice(  Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) { if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { // Creating a new object instance in the getInterceptors() method // isn't a problem as we normally cache created chains. for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); }}
return interceptorList;}

5.核心在于registry.getInterceptors(advisor); 将增强器转为List<MethodInterceptor>;如果是MethodInterceptor,直接加入到集合中,如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;转换完成返回MethodInterceptor数组;

@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {  List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);  Advice advice = advisor.getAdvice();  if (advice instanceof MethodInterceptor) {    interceptors.add((MethodInterceptor) advice);  }  for (AdvisorAdapter adapter : this.adapters) {    if (adapter.supportsAdvice(advice)) {      interceptors.add(adapter.getInterceptor(advisor));    }  }  if (interceptors.isEmpty()) {    throw new UnknownAdviceTypeException(advisor.getAdvice());  }  return interceptors.toArray(new MethodInterceptor[interceptors.size()]);}



4.目标方法div执行流程二:拦截器链的调用流程分析

运行完成后,将获得拦截器如下所示,有5个:1个默认的4个自定义的增强方法

拦截器不为空,将会运行CglibMethodInvocation.proceed()方法

else {  // We need to create a method invocation...  retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}

可以看到具体的process()函数代码如下

@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)) { 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); } }

1.如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;

if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {  return invokeJoinpoint();}

2.接着获取第0个Advice :org.springframework.aop.interceptor.ExposeInvocationInterceptor执行

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);}

3.查看invoke()的代码如下,重复调用到这个mi.proceed() 使得取下一个拦截器,进行操作


private static final ThreadLocal<MethodInvocation> invocation = new NamedThreadLocal<MethodInvocation>("Current AOP method invocation");
@Overridepublic Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); } finally { invocation.set(oldInvocation); }}

流程如图所示:

4.再次调用proceed(),运行到AspectJAfterThrowingAdvice第二个拦截器:同样是调用invoke(this)

@Override  public Object invoke(MethodInvocation mi) throws Throwable {    try {      return mi.proceed();    }    catch (Throwable ex) {      if (shouldInvokeOnThrowing(ex)) {        invokeAdviceMethod(getJoinPointMatch(), null, ex);      }      throw ex;    }  }

流程如图所示:

5.再次调用proceed(),运行到AfterReturningAdviceInterceptor第三个拦截器:同样是调用invoke(this)

@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {  Object retVal = mi.proceed();  this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());  return retVal;}

流程图如下:

6.再次调用proceed(),运行到AspectJAfterAdvice第四个拦截器:同样是调用invoke(this),但是此处进行了finally ,无论如何都会运行advice的函数。

@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {  try {    return mi.proceed();  }  finally {    invokeAdviceMethod(getJoinPointMatch(), null, null);  }}

流程图如下:

7.再次调用proceed(),运行到MethodBeforeAdviceInterceptor第五个拦截器:同样是调用invoke(this),但是此处进行了finally ,无论如何都会运行advice的before函数调用前置通知、以及目标函数。

@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {  this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );  return mi.proceed();}

流程图如下:

8.再次运行proceed()函数检测到是最后一个拦截器,并且进行出栈操作。往上返回到上一级,由于第6步的proceed()方法返回就会触发finnaly 的函数进行 调用后置通知,流程图如下:

9.在第5步,可以看到代码,没有问题才会调用afterReturn 函数完成的回调,所以第6步发生异常直接跳到第4步的,捕获异常并且调用异常的回调方法。流程图如下:




5.AOP 总结

1)、  @EnableAspectJAutoProxy 开启AOP功能

2)、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator

3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;

4)、容器的创建流程:

1)、 registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
2)、 finishBeanFactoryInitialization()初始化剩下的单实例bean
        1)、创建业务逻辑组件和切面组件
         2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
        3)、组件创建完之后, 判断组件是否需要增强
        是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);

5)、执行目标方法:

        1)、代理对象执行目标方法

        2)、CglibAopProxy.intercept();

         1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)

                2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;

                3)、效果:

              正常执行:前置通知-》目标方法-》后置通知-》返回通知

              出现异常:前置通知-》目标方法-》后置通知-》异常通知


-END-


可以关注我的公众号,免费获取价值1980元学习资料



点击“在看”,学多少都不会忘~

本文分享自微信公众号 - 阿聪的全栈之路(gh_ffab7c84fb0c)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!