【Spring】AOP注解方式实现机制

一、概述

在Spring AOP 中:

  • AnnotationAwareAspectJAutoProxyCreator是基于Bean中的AspectJ 注解来实现自动代理,在Bean创建的过程中完成对切入点的增强。
  • Spring AOP 的其他实现方式可以查看 【Spring】 AOP Base

对于 Spring AOP 使用注解的方式中,我们配置开启AOP注解

  • 可以用XML的方式:
<!-- 自动生成代理  底层就是AnnotationAwareAspectJAutoProxyCreator -->
<aop:aspectj-autoproxy />
  • 或者用注解的方式 在配置类上标注 @EnableAspectJAutoProxy 注解
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
    //业务逻辑类加入容器中
    @Bean 
    public UserDao userDao(){
        return new UserDao();
    }
    //切面类加入到容器中
    @Bean
    public MyAspect myAspect(){
        return new MyAspect();
    }
}
  • 无论是XML 还是@EnableAspectJAutoProxy 底层实现都是AnnotationAwareAspectJAutoProxyCreator

二、@EnableAspectJAutoProxy 注解分析

此注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    ...
}

  点击此注解发现 有一个@Import注解,此注解是将其中的类直接导入到Spring 容器中,再看AspectJAutoProxyRegistrar 这个类,这个类是一个注册器,我们可以通过此类手动注册bean到容器中,Spring 源码中将AnnotationAwareAspectJAutoProxyCreator通过Regist注册到了Spring容器当中关于@Import的一些总结查阅【Spring】 IOC Base初始化Bean方式的部分

  AspectJAutoProxyRegistrar类中,可以分析出internalAutoProxyCreator 就是AnnotationAwareAspectJAutoProxyCreator

三、分析AnnotationAwareAspectJAutoProxyCreator

接下来分析一下这个关键的类:
首先看AnnotationAwareAspectJAutoProxyCreator 的继承体系

  • AnnotationAwareAspectJAutoProxyCreator
    • -->AspectJAwareAdvisorAutoProxyCreator
      • -->AbstractAdvisorAutoProxyCreator
        • -->AbstractAutoProxyCreator
          • implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

可以分析出此类 实现了 BeanPostProcessor 和 BeanFactoryAware 接口,所以说此类具有后置处理器的特性和Aware接口的特点

我们就可以从两方面来分析这个类的机制:

  1. 关注后置处理器(在bean初始化完成前后做事情)、
  2. 自动装配BeanFactory

四、执行流程

下面分析一下执行的流程:

1. registerBeanPostProcessors()

  在容器中注册AnnotationAwareAspectJAutoProxyCreator

第一步: 传入配置类,创建ioc容器
第二步: 注册配置类,调用 refresh() 刷新容器
第三步: registerBeanPostProcessors(beanFactory),注册bean的后置处理器来方便拦截bean的创建,步骤如下:
(第一步): 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor

(第二步): 给容器中加别的BeanPostProcessor
(第三步): 优先注册实现了PriorityOrdered接口的BeanPostProcessor;
(第四步): 再给容器中注册实现了Ordered接口的BeanPostProcessor;
(第五步): 注册没实现优先级接口的BeanPostProcessor;

这个方法的源码如下:

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获取ioc容器已经定义了的需要创建对象的所有后置处理器
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered, 
        // Ordered, and the rest.
//对后置处理进行分类
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }
//首先注册实现了PriorityOrdered 接口的后置处理器
        // First, register the BeanPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//然后注册实现了Ordered接口的后置处理器
        // Next, register the BeanPostProcessors that implement Ordered.
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//注册常规的(即没有实现优先级接口)的后置处理器
        // Now, register all regular BeanPostProcessors.
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // Finally, re-register all internal BeanPostProcessors.
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

internalAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator】 是实现了Ordered接口的后置处理器,注册的过程,实际上就是创建BeanPostProcessor对象,保存在容器中,方法的调用流程
getBean()--> doGetBean()--> getSingleton()-->最终走到了createBean()方法,

调用getBean()
调用getBean()

在getBean中调用doGetBean
在getBean中调用doGetBean

在doGetBean中调用getSingleton
在doGetBean中调用getSingleton

getSingleton方法调用返回是null
getSingleton方法调用返回是nul

在doGetBean中开始调用createBean方法
在doGetBean中开始调用createBean方法

在createBean方法中调用了doCreateBean方法,此方法的执行流程为:

  • 创建Bean的实例:
  • populateBean;给bean的各种属性赋值
  • initializeBean:初始化bean;在此方法中:
    • invokeAwareMethods():处理Aware接口的方法回调
    • applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
    • invokeInitMethods();执行自定义的初始化方法
    • applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
    • BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功; aspectJAdvisorsBuilder

(第六步): 把BeanPostProcessor注册到BeanFactory中;beanFactory.addBeanPostProcessor(postProcessor);

以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程

2. finishBeanFactoryInitialization()

第四步: 执行finishBeanFactoryInitialization():完成BeanFactory初始化工作,创建剩下的单实例bean。

(第一步): 遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
getBean->doGetBean()->getSingleton()->

(第二步): 创建bean

下面是doGetBean方法的部分源码

protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
        final String beanName = transformedBeanName(name);
        Object bean;
//这里先尝试获取单实例bean
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
        ....
        }else {
                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
    //这里创建Bean实例
                                return createBean(beanName, mbd, args);
                            }
                ...
                }       
      ...
            return (T) bean;
    }
  • 先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;只要创建好的Bean都会被缓存起来
  • createBean(),创建bean,下面是createBean方法的流程分析:

  • 1.resolveBeforeInstantiation(beanName, mbdToUse):希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续

    • 后置处理器先尝试返回对象;
    • bean = applyBeanPostProcessorsBeforeInstantiation():拿到所有后置处理器,如果是 InstantiationAwareBeanPostProcessor; 就执行postProcessBeforeInstantiation
    if (bean != null) {
    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
    //如果是这个类型的处理器,就执行其postProcessBeforeInstantiation() 方法
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    if (result != null) {
    return result;
    }
    }
    }
    return null;
    }
    • AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
    • BeanPostProcessor是在Bean对象创建完成初始化前后调用的
    • InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的
  • 2.doCreateBean(beanName, mbdToUse, args):真正的去创建一个bean实例,此方法的流程在上面已经介绍 (第三.(五)步中图片下面)

3. InstantiationAwareBeanPostProcessor后置处理器的执行逻辑

  经过上面的分析可以知道,在所有bean创建之前会有一个拦截:由于 AnnotationAwareAspectJAutoProxyCreator 是一个InstantiationAwareBeanPostProcessor 类型的后置处理器,它会调用postProcessBeforeInstantiation()方法

(一):每一个bean创建之前,调用postProcessBeforeInstantiation();
关注 业务逻辑类切面类的创建

  源码如下:

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);
        
//1.判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }

//2.判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
//3.是否需要跳过
//获取候选的增强器(切面里面的通知方法)
//【List<Advisor> candidateAdvisors】每一个封装的通知方法的
//增强器是 InstantiationModelAwarePointcutAdvisor类型;
//判断每一个增强器是否是 AspectJPointcutAdvisor 类型的,
//如果是,返回true;如果不是调用父类的【shouldSkip()-->永远返回false】
            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;
    }

(二):创建完业务类对象之后调用执行postProcessAfterInitialization

  源码如下:

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;
    }
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.
/*1.获取当前bean的所有增强器(通知方法) getAdvicesAndAdvisorsForBean() 内部流程:
*  1.1找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
*  1.2获取到能在bean使用的增强器。
*  1.3给增强器排序
*/
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
//2.保存当前bean在advisedBeans中;
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            
/*3. 如果当前bean需要增强,创建当前bean的代理对象;
 *  1)、获取所有增强器(通知方法)
 *  2)、保存到proxyFactory
 *  3)、创建代理对象:Spring自动决定
 *      JdkDynamicAopProxy(config);jdk动态代理;
 *      ObjenesisCglibAopProxy(config);cglib的动态代理;
 *  4)、给容器中返回当前组件增强了的代理对象;
 *  5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
*/
            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;
    }

4. 目标方法执行

  经过上面的流程后,容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。

代理对象
代理对象

  通过Debug的几次进入进出之后,可以进入到CglibAopProxy.intercept()方法,此方法用于拦截目标方法的执行

源码如下:

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();
        }
    
/*
* 1. 根据ProxyFactory对象获取将要执行的目标方法拦截器链;
*   方法源码见下面
*   1.1 List<Object> interceptorList保存所有拦截器 5
*   一个默认的ExposeInvocationInterceptor 和 4个增强器;
*   1.2 遍历所有的增强器,将其转为Interceptor;
*   registry.getInterceptors(advisor);
*     1.2.1 将增强器转为List<MethodInterceptor>;
*     1.2.2 如果是MethodInterceptor,直接加入到集合中
*     1.2.3 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
*   转换完成返回MethodInterceptor数组;
*/  
        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())) {
/*
* 2.如果没有拦截器链,直接执行目标方法;
*  拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
*/
            // 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 {
    
/*
* 3. 如果有拦截器链,把需要执行的目标对象,目标方法,
*   拦截器链等信息传入,创建一个 CglibMethodInvocation 对象,
*   并调用Object retVal =  mi.proceed();
*/
            // 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);
        }
    }
}

第一部分,得到拦截器链

上面源码 1 中调用的方法

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

上面方法中调用了如下方法:

public 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.

/**
* 1.1 List<Object> interceptorList保存所有拦截器 5
*   一个默认的ExposeInvocationInterceptor 和 4个增强器;
*/
        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)) {
                
                
/*
1.2 遍历所有的增强器,将其转为Interceptor;
*/
                    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;
    }

上面方法又调用了如下方法:

@Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
        Advice advice = advisor.getAdvice();
/*
* 1.2.1 将增强器转为List<MethodInterceptor>;
* 1.2.2 如果是MethodInterceptor,直接加入到集合中,如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
* 1.2.3转换完成返回MethodInterceptor数组;
*/
        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()]);
    }

  经过上面中的 1 我们得到了拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)

第二部分,拦截器链的触发过程

上面源码 3 中调用的方法

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大小一样(指定到了最后一个拦截器)执行目标方法;
  • 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
    • 拦截器链的机制,保证通知方法与目标方法的执行顺序;

链式调用
链式调用

总结

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
  4. 容器的创建流程:
    • registerBeanPostProcessors():注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
    • finishBeanFactoryInitialization():初始化剩下的单实例bean
      • 创建业务逻辑组件和切面组件;
      • AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程;
      • 组件创建完之后,判断组件是否需要增强,如果需要增强:将切面的通知方法包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
  5. 执行目标方法:代理对象执行目标方法
    • CglibAopProxy.intercept();
      • 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
      • 利用拦截器的链式机制,依次进入每一个拦截器进行执行;
      • 效果:
        • 正常执行:前置通知-》目标方法-》后置通知-》返回通知
        • 出现异常:前置通知-》目标方法-》后置通知-》异常通知

猜你喜欢

转载自www.cnblogs.com/haoworld/p/springaop-zhu-jie-fang-shi-shi-xian-ji-zhi.html